如何使对象围绕目标旋转,具有随机高度,并具有更改旋转半径的选项?

huangapple go评论72阅读模式
英文:

How to make object rotate around target with random height and with option to change the rotation radius?

问题

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotateAroundTarget : MonoBehaviour
{
    public Transform target;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        transform.RotateAround(target.transform.position, new Vector3(0, 1, 0), 20 * Time.deltaTime);
        transform.position = new Vector3(0, Random.Range(0, 5f), 0);
    }
}
英文:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotateAroundTarget : MonoBehaviour
{
    public Transform target;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        transform.RotateAround(target.transform.position, new Vector3(0,1,0), 20 * Time.deltaTime);
        transform.position = new Vector3(0,Random.Range(0,5f),0);
    }
}

the RotateAround was working fine but once i added the Random.Range part the object is no just jumping very fast.

i guess i need somehow to add a delay between the random pickups ? but not sure how to make it smooth so the object will rotate around the target and from time to time randomly will change the height smooth up and down.

and how to add an option to change the rotation around the radius around the target?

tried the code above but it's still far away from what I wanted.

I tried using InvokeRepeating but then the transform is not rotating around anymore.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotateAroundTarget : MonoBehaviour
{
    public Transform target;

    // Start is called before the first frame update
    void Start()
    {
        InvokeRepeating("ChangePosition", 0, 2);
    }

    // Update is called once per frame
    void Update()
    {
        transform.RotateAround(target.transform.position, new Vector3(0,1,0), 20 * Time.deltaTime); 
    }

    private void ChangePosition()
    {
        transform.position = new Vector3(0, Random.Range(0, 5f), 0);
    }
}

答案1

得分: 0

以下是代码的翻译部分:

有关您的代码存在一些问题。首先,在以下代码中设置位置:

transform.position = new Vector3(0, Random.Range(0, 5f), 0);

会完全覆盖之前的 RotateAround 导致的 X/Z 改变。这就是为什么一旦引入这段代码,您的旋转停止的原因。要在不丢失 X/Z 值的情况下设置位置,您可以使用:

transform.position = new Vector3(
    transform.position.x,
    Random.Range(0, 5f),
    transform.position.z);

现在,旋转再次正常工作。但高度的更改仍然不稳定,因为您的代码在每一帧都会设置新的随机高度。我们可以采取什么替代方案呢?

让我们尝试将最大高度变化限制为特定速度,并仅在达到先前的高度目标时设置新的高度目标。因此,您的代码可能如下所示:

public class RotateAroundTarget : MonoBehaviour
{
    public Transform target;
    public float verticalSpeed = 20;
    public float radius = 10;

    private float targetHeight;

    // Start is called before the first frame update
    void Start()
    {
        // 使用一个高度来初始化,以开始向该高度移动
        targetHeight = GetNewTargetHeight();

        // 如果我们从目标物体的一定距离处开始,那么当我们围绕它旋转时,它将成为我们的半径
        transform.position = new Vector3(0, 0, radius);
    }

    // Update is called once per frame
    void Update()
    {
        transform.RotateAround(target.transform.position,
            new Vector3(0, 1, 0), 20 * Time.deltaTime);

        // 就像您的旋转速率一样,我们根据游戏时间来进行缩放
        float maxHeightChange = verticalSpeed * Time.deltaTime;
        float targetHeightDelta = targetHeight - transform.position.y;

        if (maxHeightChange >= Mathf.Abs(targetHeightDelta)){
            // 如果当前高度足够接近目标高度,我们可以将其移动到那里,然后生成一个新的高度目标
            transform.position = new Vector3(
                transform.position.x,
                targetHeight,
                transform.position.z);
            targetHeight = GetNewTargetHeight();
        }
        else{
            // 否则,通过速度限制高度变化的幅度,并将其应用于当前高度
            float allowedHeightChange = Mathf.Clamp(
                targetHeightDelta,
                -maxHeightChange,
                maxHeightChange);
            transform.position = new Vector3(
                transform.position.x,
                transform.position.y + allowedHeightChange,
                transform.position.z);
        }
    }

    private float GetNewTargetHeight()
    {
        return Random.Range(0, 5f);
    }
}

请注意,这是代码的翻译部分,不包括代码中的注释。

英文:

There are a couple issues with your code. First, setting the position with:

transform.position = new Vector3(0,Random.Range(0,5f),0);

will completely overwrite any X/Z change caused by the prior RotateAround. That's why your rotation stopped as soon as you introduced this code. To set the position without losing the X/Z values, you could use:

transform.position = new Vector3(
    transform.position.x,
    Random.Range(0,5f),
    transform.position.z);

So now, the rotation works again. But the height changes are still erratic because your code is setting a new random height every frame. What can we do instead?

Let's try constraining the maximum height change to a certain speed, and only set a new height target when the previous one has been reached. So your code might look like:

<!-- language: lang-cs -->

public class RotateAroundTarget : MonoBehaviour
{
    public Transform target;
    public float verticalSpeed = 20;
    public float radius = 10;

    private float targetHeight;

    // Start is called before the first frame update
    void Start()
    {
        // Initialize with a height to start moving toward
        targetHeight = GetNewTargetHeight();

        // If we start at a given distance away from the target, then this
        // will become our radius when we RotateAround it
        transform.position = new Vector3(0, 0, radius);
    }

    // Update is called once per frame
    void Update()
    {
        transform.RotateAround(target.transform.position,
            new Vector3(0,1,0), 20 * Time.deltaTime);

        // Just like your rotation rate, we scale this based on game time
        float maxHeightChange = verticalSpeed * Time.deltaTime;
        float targetHeightDelta = targetHeight - transform.position.y;

        if (maxHeightChange &gt;= Mathf.Abs(targetHeightDelta)){
            // If the current height is close enough to the target, we can move it
            // there and then generate a new height to go towards
            transform.position = new Vector3(
                transform.position.x,
                targetHeight,
                transform.position.z);
            targetHeight = GetNewTargetHeight();
        }
        else{
            // Otherwise, limit the magnitude of the height change by the speed and
            // apply it to the current height
            float allowedHeightChange = Mathf.Clamp(
                targetHeightDelta,
                -maxHeightChange,
                maxHeightChange);
            transform.position = new Vector3(
                transform.position.x,
                transform.position.y + allowedHeightChange,
                transform.position.z);
        }
    }

    private float GetNewTargetHeight()
    {
        return Random.Range(0,5f);
    }
}

huangapple
  • 本文由 发表于 2023年2月14日 07:15:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/75442057.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定