旋转四元数
Rotating Quaternions
这是向玩家发射激光的炮塔代码,一个胶囊。激光目前以错误的旋转方式出现,它是直立的,而不是激光通常看起来的样子。
到目前为止,我的代码运行完美,没有错误。我该如何解决这个问题?
void SpawnLaser(int iter)
{
for (var j = 0; j < 5; j++)
{
Vector3 pos = transform.position;
var rotation = transform.rotation;
rotation *= Quaternion.Euler(0, 90, 0);
Instantiate(projectile, pos, rotation);
}
}
我不完全确定您的代码的目标,但我可以提供一些指导,并且可以在我对您的问题了解更多后编辑我的答案。
你的产卵没有问题,问题很可能与你的运动有关。另一个问题是你的旋转被乘以一个局部变量,所以每个激光都会指向同一个方向。
// my laser object
[SerializeField] private GameObject projectile = null;
private void Update()
{
// when I hit space, spawn new lasers
if (Input.GetKeyDown(KeyCode.Space))
SpawnLaser();
}
void SpawnLaser()
{
// keep the rotation outside of the loop so the *= 90 will change the angle the object is positioned to look at
var rotation = transform.rotation;
// as the angle is *= 90, there are only 4 possible rotations, so I would adjust your loop or rotation product
for (int j = 0; j < 4; j++)
{
Vector3 pos = transform.position;
rotation *= Quaternion.Euler(0, 90, 0);
// I attached a rigidbody to move the objects, if your objects or your player do not have rigidbodies, then they will not collide
Rigidbody laserObj = Instantiate(projectile, pos, rotation).GetComponent<Rigidbody>();
// I am adding a force of 10 in the forward direction of my newly spawned laser
laserObj.AddForce(laserObj.transform.forward * 10f);
}
}
确保将刚体组件和碰撞器组件添加到正在生成的预制件中。您需要做的另一件事是在激光器上添加一层,这样它们就不会相互碰撞。查看 Layer-based collisions。确保给你的激光添加一层并禁用与自身的碰撞,这样它就不会与其他激光发生碰撞。
至于你的碰撞问题,有很多原因,所以我不会在这里列出它们,而是 link 到 an answer that goes over the possible reason。
编辑:在提供更多信息后,这可能更接近您想要实现的目标。
// this script is on the object that will be firing the laser, a turret, gun, etc.
[SerializeField] private GameObject projectile = null; // laser prefab
[SerializeField] private Transform playerObjectPos = null; // reference to what we are trying to aim at (player, enemy, etc.)
private float laserFiringForce = 10f;
private void Update()
{
// when I hit space, spawn new laser spawns
if (Input.GetKeyDown(KeyCode.Space))
SpawnLaser(playerObjectPos);
}
/// <summary>
/// Spawns a laser aiming at a specified target
/// </summary>
/// <param name="target"></param>
void SpawnLaser(in Transform target)
{
// lock our rotation to only Y-axis
Vector3 targetPosition = new Vector3(target.position.x, transform.position.y, target.position.z);
// have our turret / player / etc. look at the target position
transform.LookAt(targetPosition);
// instantiate a laser at the position of our turret / player and have its rotation aim in the same direction as our turret / player
// while grabbing the reference to the rigidbody component on the laser so we can add a force to it (Note: You can have the movement logic on the laser itself instead of doing it here)
Rigidbody laserObj = Instantiate(projectile, transform.position, Quaternion.LookRotation(transform.forward, Vector3.up)).GetComponent<Rigidbody>();
// add a force in the direction the laser is facing so it moves
laserObj.AddForce(laserObj.transform.forward * laserFiringForce);
}
我会研究 FPS 或 3D 炮塔游戏的教程。考虑到这些问题,我认为您对编程、Unity 或两者都不熟悉。如果这是您的第一个项目,请查看教程,创建它并将其更改为更适合您的项目。完成几个教程后,您应该对 Unity 有更好的了解。如果您完全不熟悉编程,我也会考虑研究 类、c# 和一般编程的文档等。
要开始使用 Unity,请尝试 Brackey's。我 link 编辑的教程是他制作的 3D 塔防游戏的第 4 集,他在其中制作了炮塔。
这是向玩家发射激光的炮塔代码,一个胶囊。激光目前以错误的旋转方式出现,它是直立的,而不是激光通常看起来的样子。
到目前为止,我的代码运行完美,没有错误。我该如何解决这个问题?
void SpawnLaser(int iter)
{
for (var j = 0; j < 5; j++)
{
Vector3 pos = transform.position;
var rotation = transform.rotation;
rotation *= Quaternion.Euler(0, 90, 0);
Instantiate(projectile, pos, rotation);
}
}
我不完全确定您的代码的目标,但我可以提供一些指导,并且可以在我对您的问题了解更多后编辑我的答案。
你的产卵没有问题,问题很可能与你的运动有关。另一个问题是你的旋转被乘以一个局部变量,所以每个激光都会指向同一个方向。
// my laser object
[SerializeField] private GameObject projectile = null;
private void Update()
{
// when I hit space, spawn new lasers
if (Input.GetKeyDown(KeyCode.Space))
SpawnLaser();
}
void SpawnLaser()
{
// keep the rotation outside of the loop so the *= 90 will change the angle the object is positioned to look at
var rotation = transform.rotation;
// as the angle is *= 90, there are only 4 possible rotations, so I would adjust your loop or rotation product
for (int j = 0; j < 4; j++)
{
Vector3 pos = transform.position;
rotation *= Quaternion.Euler(0, 90, 0);
// I attached a rigidbody to move the objects, if your objects or your player do not have rigidbodies, then they will not collide
Rigidbody laserObj = Instantiate(projectile, pos, rotation).GetComponent<Rigidbody>();
// I am adding a force of 10 in the forward direction of my newly spawned laser
laserObj.AddForce(laserObj.transform.forward * 10f);
}
}
确保将刚体组件和碰撞器组件添加到正在生成的预制件中。您需要做的另一件事是在激光器上添加一层,这样它们就不会相互碰撞。查看 Layer-based collisions。确保给你的激光添加一层并禁用与自身的碰撞,这样它就不会与其他激光发生碰撞。
至于你的碰撞问题,有很多原因,所以我不会在这里列出它们,而是 link 到 an answer that goes over the possible reason。
编辑:在提供更多信息后,这可能更接近您想要实现的目标。
// this script is on the object that will be firing the laser, a turret, gun, etc.
[SerializeField] private GameObject projectile = null; // laser prefab
[SerializeField] private Transform playerObjectPos = null; // reference to what we are trying to aim at (player, enemy, etc.)
private float laserFiringForce = 10f;
private void Update()
{
// when I hit space, spawn new laser spawns
if (Input.GetKeyDown(KeyCode.Space))
SpawnLaser(playerObjectPos);
}
/// <summary>
/// Spawns a laser aiming at a specified target
/// </summary>
/// <param name="target"></param>
void SpawnLaser(in Transform target)
{
// lock our rotation to only Y-axis
Vector3 targetPosition = new Vector3(target.position.x, transform.position.y, target.position.z);
// have our turret / player / etc. look at the target position
transform.LookAt(targetPosition);
// instantiate a laser at the position of our turret / player and have its rotation aim in the same direction as our turret / player
// while grabbing the reference to the rigidbody component on the laser so we can add a force to it (Note: You can have the movement logic on the laser itself instead of doing it here)
Rigidbody laserObj = Instantiate(projectile, transform.position, Quaternion.LookRotation(transform.forward, Vector3.up)).GetComponent<Rigidbody>();
// add a force in the direction the laser is facing so it moves
laserObj.AddForce(laserObj.transform.forward * laserFiringForce);
}
我会研究 FPS 或 3D 炮塔游戏的教程。考虑到这些问题,我认为您对编程、Unity 或两者都不熟悉。如果这是您的第一个项目,请查看教程,创建它并将其更改为更适合您的项目。完成几个教程后,您应该对 Unity 有更好的了解。如果您完全不熟悉编程,我也会考虑研究 类、c# 和一般编程的文档等。
要开始使用 Unity,请尝试 Brackey's。我 link 编辑的教程是他制作的 3D 塔防游戏的第 4 集,他在其中制作了炮塔。