Home > front end >  How can I control the radius from the center of the rotating object aorund another object?
How can I control the radius from the center of the rotating object aorund another object?

Time:09-17

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

public class SimpleRotate : MonoBehaviour
{
    public GameObject objToRotateAround;
    [Header("The axis by which it will rotate around")]
    public Vector3 axis;
    [Header("Angle covered per update")]
    public float angle;
    public bool randomAngle = false;
    public float upperLimit, lowerLimit, delay;

    private float height, prevHeight, time, prevAngle;

    // Update is called once per frame
    void Update()
    {
        time  = Time.deltaTime;
        if (time > delay)
        {
            prevAngle = angle;
            prevHeight = height;
            height = Random.Range(lowerLimit, upperLimit);
            prevAngle = Random.Range(-0.25f, 0.25f);
            time = 0;
        }

        if (randomAngle)
        {
            transform.RotateAround(objToRotateAround.transform.position, axis.normalized,
                Mathf.Lerp(prevAngle, angle, time));
        }
        else
        {
            transform.RotateAround(objToRotateAround.transform.position, axis.normalized,
                angle);
        }

        transform.position = new Vector3(transform.position.x, Mathf.Lerp(prevHeight, height, time), transform.position.z);
    }
}

The angle if I change it to small value the object will rotate slower and higher value faster. So I don't understand, The angle is just a speed factor ? Than why not calling the variable speed instead angle ?

The second problem is how can I control at runtime the radius of the rotation ? For example if I want the object to rotate closer the target object he rotate around or much far away.

CodePudding user response:

Than why not calling the variable speed instead angle?

This is c#, you can call your fields and variables whatever is convenient for you.

So go ahead and call it whatever you want

Personally I would rather call it anglePerSecond and later properly multiply it by Time.deltaTime.

You current code is frame-rate dependent meaning you rotate a fixed angle per frame which is usually never what you want to do.

Like e.g. (Note: I removed the randomAngle part for now since it didn't make much sense to me either)

public class SimpleRotate : MonoBehaviour
{
    public GameObject objToRotateAround;
    [Header("The axis by which it will rotate around")]
    public Vector3 axis;
    [Header("Angle covered per Second")]
    public float anglePerSecond;

    public float upperLimit; 
    public float lowerLimit;
    public float delay;

    private float height;
    private float prevHeight;
    private float time;

    void Update()
    {
        time  = Time.deltaTime;
        if (time > delay)
        {
            prevHeight = height;
            height = Random.Range(lowerLimit, upperLimit);

            time = 0;
        }

        // Rotate with a frame-rate independent angle per second
        transform.RotateAround(objToRotateAround.transform.position, axis, anglePerSecond * Time.deltaTime);

        // For the Lerp you want a factor between 0 and 1
        // not between 0 and delay
        // => divide by delay gives you a factor between 0 and 1   
        transform.position = new Vector3(transform.position.x, Mathf.Lerp(prevHeight, height, time / delay), transform.position.z);
    }
}

The second problem is how can I control at runtime the radius of the rotation?

You rotate your object around another object's position using RotateAround.

As you can see the rotation radius depends on one single factor: The distance between your object and the rotation pivot.

So move this object closer to the objToRotateAround => radius smaller

You could adjust this on runtime using e.g.

[SerializeField] private float radius;

private float lastRadius;

private void Start ()
{
    ApplyRadius();
}

private void Update ()
{
    // Check if the radius was changed
    if(!Mathf.Approximately(radius, lastRadius))
    {
        ApplyRadius ();
    }

    // ... Rest of your code
}

private void ApplyRadius()
{
    // Get the dorection vector from the pivot to your current object position
    var direction = (transform.position - objectToRotateAround.transform.position).normalized;

    // set your object in the same direction but at distance of radius
    transform.position = objectToRotateAround   direction * radius;

    lastRadius = radius;
}
  • Related