简体   繁体   中英

Clamping a Rotating GameObject

I have tried to clamp a rotation on one of my Gameobjects for over a week now and still have no luck. This is my code so far and what I have tried:

        if ((transform.rotation.eulerAngles.z > 330  ) && (Input.GetKey(KeyCode.RightArrow)))
    {
    
    transform.Rotate(Vector3.forward * speed * Time.deltaTime * -1);
    }

    if ((transform.rotation.eulerAngles.z < 30) && (Input.GetKey(KeyCode.LeftArrow)))
    {
    
    transform.Rotate(Vector3.forward * speed * Time.deltaTime);
    }

Then I went on and tried this:

    if (Input.GetKey(KeyCode.RightArrow))
    {
    
    transform.Rotate(Vector3.forward * speed * Time.deltaTime * -1);
    }

    if (Input.GetKey(KeyCode.LeftArrow))
    {
    
    transform.Rotate(Vector3.forward * speed * Time.deltaTime);
    }
    transform.localEulerAngles = new Vector3( 0 , 0 , Mathf.Clamp(0, -30, 30) );

But I still have no luck. Btw I am using C# 这是它看起来的游戏类型,我也希望玩家在没有按下任何键时旋转回 0

This is the type of game that it looks like and I also wish for the player to rotate back to 0 when no key is pressed

Your second code example is much cleaner. The only issue is in your last line:

transform.localEulerAngles = new Vector3( 0 , 0 , Mathf.Clamp(0, -30, 30) ); //this always returns [0,0,0]

I think you mean:

float rotation = 0;
if (Input.GetKey(KeyCode.RightArrow))
{        
   rotation -= 1;
}

if (Input.GetKey(KeyCode.LeftArrow))
{
    rotation += 1; 
}
float newZAngle = transform.localEulerAngles.Z + (speed*Time.deltaTime*rotation);
transform.localEulerAngles = new Vector3( 0 , 0 , Mathf.Clamp(newZAngle, -30, 30) );

I wrote that without an IDE, so there might be some typos. Also, I haven't used Unity in a while, I'm just going off memory.

Also, I changed rotation using += / -= so that when you hold both arrows it doesn't rotate.

I think the issue has to do with how you are handling your angles. Here is a link to something from 2014 (but should still be relevant in your situation since it appears to be a logical issue). There is also someone who updated a reply from this year. Ill attach a screenshot for the person who specifically discusses how to clamp euler angles (incase you dont want to click the link) Clamping angle between two values

在此处输入图片说明

Your main issue was already mentioned:

var x = Mathf.Clamp(0, -30, 30);

will always return 0 .

In general the best approach for this is simply storing the rotation local and not go through the eulerAngles (local/global doesn't matter for the point)

Because, there is more than one way to represent any given rotation using Euler angles, the values you read back out may be quite different from the values you assigned. This can cause confusion if you are trying to gradually increment the values to produce animation.

So I would rather use

private float zRotation;

private void Update ()
{
    if (Input.GetKey(KeyCode.RightArrow))
    {
        zRotation -= speed * Time.deltaTime;
    }

    if (Input.GetKey(KeyCode.LeftArrow))
    {
        zRotation += speed * Time.deltaTime;
    }

    zRotation = Mathf.Clamp(zRotation, -30, 30);

    transform.localRotation = Quaternion.Euler(0, 0, zRotation);
}

This is what I have @AniOptics:

    void Update()
{
    if (Input.GetKey(KeyCode.RightArrow))
    {        
       rotation = -1;
    }

    if (Input.GetKey(KeyCode.LeftArrow))
    {
        rotation = 1; 
    }

    if ((!Input.GetKey(KeyCode.RightArrow)) && 
    ((!Input.GetKey(KeyCode.RightArrow))))
    {
        if (transform.eulerAngles.z < 0){
        rotation = 1;
        
        }
        if (transform.eulerAngles.z > 0){
        rotation = -1;
        }
        
    }


    float newZAngle = transform.localEulerAngles.z + (speed * Time.deltaTime * rotation);
    transform.Rotate(Vector3.forward * newZAngle * Time.deltaTime);

    
}
public float ModularClamp(float val, float min, float max, float rangemin = -180f, float rangemax = 180f) 
{
    var modulus = Mathf.Abs(rangemax - rangemin);
    if((val %= modulus) < 0f) val += modulus;
    return Mathf.Clamp(val + Mathf.Min(rangemin, rangemax), min, max);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM