当脚本附加到多个对象时旋转单个对象
Rotation of a single object when script is attached to multiple objects
我在 Unity 中有一个游戏,我在其中添加了三个对象(立方体、圆柱体、胶囊)。对于这些游戏对象,我添加了一个脚本,当他们按下左键单击和 x、y 或 z 时,它们会沿轴旋转,从而沿各自的轴旋转对象。但是当我尝试旋转单个对象时,其他对象也会旋转。如何在不影响其他对象的情况下旋转每个对象。
if (Input.GetMouseButton(0) && Input.GetKey(KeyCode.Z))
{
transform.RotateAround(transform.position, transform.forward, Time.deltaTime * 90f);
}
if (Input.GetMouseButton(0) && Input.GetKey(KeyCode.X))
{
transform.RotateAround(transform.position, transform.right, Time.deltaTime * 90f);
}
if (Input.GetMouseButton(0) && Input.GetKey(KeyCode.Y))
{
transform.RotateAround(transform.position, transform.up, Time.deltaTime * 90f);
}
尝试输入条件分别为 Input.GetKey(KeyCode.X)
、Input.GetKey(KeyCode.Y)
、Input.GetKey(KeyCode.Z)
的三个单独的单一行为:
if (Input.GetMouseButton(0) && Input.GetKey(KeyCode.X)) {
transform.RotateAround(transform.position, transform.forward, Time.deltaTime * 90f);
}
transform
适用于 Monobehvaiour
附加到的游戏对象的转换,因此如果您将脚本附加到许多游戏对象,则该逻辑适用于所有游戏对象。
您需要制作 3 个不同的 Monobehaviours
并分别处理输入逻辑,或者制作一个全局 Monobehaviour
旋转处理程序,在其中为每个游戏对象保留一个引用,以便您可以处理每个变换分别。
我假设您要实现的目标是
- 用鼠标光标单击对象并按住
- 然后使用相应的键旋转此对象。
你实际上只需要一个脚本,不是在每个对象上,而是场景中的一个(比如中央控制器)
public class ObjectRotator : MonoBehaviour
{
[SerializeField] private Camera _camera;
//Optionally if you only want to hit objects on (a) certain layer(s)
//[SerializeField] private LayerMask layers;
private void Awake ()
{
if(!_camera) _camera = Camera.main;
}
private void Update ()
{
if(Input.GetMouseButton(0))
{
// Shoot a Raycast from the mouse position into your scene to check if you hit an object
var ray = _camera.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out var hit)
// or if using the layer mask
//if(Physics.Raycast(ray, out var hit, float.positiveInfinity, layers)
{
if (Input.GetKey(KeyCode.Z))
{
// Instead of using RotateAround rather use Rotate which rotated around this object's
// pivot position anyway. By default it is in local space so also no need for transform.forward etc
hit.transform.Rotate(Vector3.forward * Time.deltaTime * 90f);
}
if (Input.GetKey(KeyCode.X))
{
hit.transform.Rotate(Vector3.right * Time.deltaTime * 90f);
}
if (Input.GetKey(KeyCode.Y))
{
hit.transform.Rotate(Vector3.up * Time.deltaTime * 90f);
}
}
}
}
}
注意:要求您的目标对象具有碰撞器(和选定的图层)
作为替代方案,如果您更愿意使用每个对象一个脚本的解决方案,您可以使用例如
public class Rotation : MonoBehaviour
{
// This is called by Unity when the mouse is going down while hovering this object's collider
private void OnMouseDown ()
{
// Start the RotationRoutine
StartCoroutine (RotationRoutine());
}
// This is called when the mouse button goes up while hovering this object's collider
private void OnMouseUp()
{
// To simplify things just stop any routine started by this behavior
StopAllCoroutines ();
}
// Also stop when the mouse leaves this object's collider while still being pressed
private void OnMouseExit()
{
StopAllCoroutines ();
}
private void RotationRoutine()
{
// Whut?! No worries ;) This is fine in a Coroutine as soon as you "yield" somewhere inside
while(true)
{
if (Input.GetKey(KeyCode.Z))
{
transform.Rotate(Vector3.forward * Time.deltaTime * 90f);
}
if (Input.GetKey(KeyCode.X))
{
transform.Rotate(Vector3.right * Time.deltaTime * 90f);
}
if (Input.GetKey(KeyCode.Y))
{
transform.Rotate(Vector3.up * Time.deltaTime * 90f);
}
// Basically tells Unity to "pause" here, render this frame and
// continue from here in the next frame
yield return null;
}
}
}
我在 Unity 中有一个游戏,我在其中添加了三个对象(立方体、圆柱体、胶囊)。对于这些游戏对象,我添加了一个脚本,当他们按下左键单击和 x、y 或 z 时,它们会沿轴旋转,从而沿各自的轴旋转对象。但是当我尝试旋转单个对象时,其他对象也会旋转。如何在不影响其他对象的情况下旋转每个对象。
if (Input.GetMouseButton(0) && Input.GetKey(KeyCode.Z))
{
transform.RotateAround(transform.position, transform.forward, Time.deltaTime * 90f);
}
if (Input.GetMouseButton(0) && Input.GetKey(KeyCode.X))
{
transform.RotateAround(transform.position, transform.right, Time.deltaTime * 90f);
}
if (Input.GetMouseButton(0) && Input.GetKey(KeyCode.Y))
{
transform.RotateAround(transform.position, transform.up, Time.deltaTime * 90f);
}
尝试输入条件分别为 Input.GetKey(KeyCode.X)
、Input.GetKey(KeyCode.Y)
、Input.GetKey(KeyCode.Z)
的三个单独的单一行为:
if (Input.GetMouseButton(0) && Input.GetKey(KeyCode.X)) {
transform.RotateAround(transform.position, transform.forward, Time.deltaTime * 90f);
}
transform
适用于 Monobehvaiour
附加到的游戏对象的转换,因此如果您将脚本附加到许多游戏对象,则该逻辑适用于所有游戏对象。
您需要制作 3 个不同的 Monobehaviours
并分别处理输入逻辑,或者制作一个全局 Monobehaviour
旋转处理程序,在其中为每个游戏对象保留一个引用,以便您可以处理每个变换分别。
我假设您要实现的目标是
- 用鼠标光标单击对象并按住
- 然后使用相应的键旋转此对象。
你实际上只需要一个脚本,不是在每个对象上,而是场景中的一个(比如中央控制器)
public class ObjectRotator : MonoBehaviour
{
[SerializeField] private Camera _camera;
//Optionally if you only want to hit objects on (a) certain layer(s)
//[SerializeField] private LayerMask layers;
private void Awake ()
{
if(!_camera) _camera = Camera.main;
}
private void Update ()
{
if(Input.GetMouseButton(0))
{
// Shoot a Raycast from the mouse position into your scene to check if you hit an object
var ray = _camera.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out var hit)
// or if using the layer mask
//if(Physics.Raycast(ray, out var hit, float.positiveInfinity, layers)
{
if (Input.GetKey(KeyCode.Z))
{
// Instead of using RotateAround rather use Rotate which rotated around this object's
// pivot position anyway. By default it is in local space so also no need for transform.forward etc
hit.transform.Rotate(Vector3.forward * Time.deltaTime * 90f);
}
if (Input.GetKey(KeyCode.X))
{
hit.transform.Rotate(Vector3.right * Time.deltaTime * 90f);
}
if (Input.GetKey(KeyCode.Y))
{
hit.transform.Rotate(Vector3.up * Time.deltaTime * 90f);
}
}
}
}
}
注意:要求您的目标对象具有碰撞器(和选定的图层)
作为替代方案,如果您更愿意使用每个对象一个脚本的解决方案,您可以使用例如
public class Rotation : MonoBehaviour
{
// This is called by Unity when the mouse is going down while hovering this object's collider
private void OnMouseDown ()
{
// Start the RotationRoutine
StartCoroutine (RotationRoutine());
}
// This is called when the mouse button goes up while hovering this object's collider
private void OnMouseUp()
{
// To simplify things just stop any routine started by this behavior
StopAllCoroutines ();
}
// Also stop when the mouse leaves this object's collider while still being pressed
private void OnMouseExit()
{
StopAllCoroutines ();
}
private void RotationRoutine()
{
// Whut?! No worries ;) This is fine in a Coroutine as soon as you "yield" somewhere inside
while(true)
{
if (Input.GetKey(KeyCode.Z))
{
transform.Rotate(Vector3.forward * Time.deltaTime * 90f);
}
if (Input.GetKey(KeyCode.X))
{
transform.Rotate(Vector3.right * Time.deltaTime * 90f);
}
if (Input.GetKey(KeyCode.Y))
{
transform.Rotate(Vector3.up * Time.deltaTime * 90f);
}
// Basically tells Unity to "pause" here, render this frame and
// continue from here in the next frame
yield return null;
}
}
}