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;
}