如何解决当脚本附加到多个对象时单个对象的旋转
我在 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)
的三个单独的 monobehaviour:
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;
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。