Sooo… I had a little trouble scaling a quaternion, so I cheated and used eulerAngle… but I added oscillation for rotation and scale to the method using an enum and a switch. Lots of fun. Also got rid of the disallow so you can add multiples for different transforms and periods. Loving this course.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//[DisallowMultipleComponent]
public class oscillate : MonoBehaviour
{
public enum TransformType {position, rotation, scale};
public TransformType targetTransform = TransformType.position;
Quaternion
Vector3 startingPosition;
Vector3 startingRotation;
Vector3 startingScale;
[SerializeField] Vector3 movementVector = new Vector3(10f, 10f, 10f);
[SerializeField] float period = 2f;
const float tau = Mathf.PI * 2;
// [Range(0, 1)] [SerializeField] float movementScale;
// ^^^^^^^^^^^^^--- the range bit in front adds a slider to the unity UI
void Start()
{
startingPosition = transform.position;
startingRotation = transform.rotation.eulerAngles;
startingScale = transform.localScale;
}
void Update()
{
if (period <= Mathf.Epsilon) { return; }
float sinNormalized;
Vector3 offset;
switch (targetTransform)
{
case (TransformType.position):
sinNormalized = getSine(true);
offset = movementVector * sinNormalized;
transform.position = startingPosition + offset;
break;
case (TransformType.rotation): // Can't quite figure out how to scale a quaternion yet.
sinNormalized = getSine(false);
offset = movementVector * sinNormalized;
transform.Rotate(startingRotation + offset);
break;
case (TransformType.scale):
sinNormalized = getSine(true);
offset = movementVector * sinNormalized;
transform.localScale = startingScale + offset;
break;
}
}
float getSine(bool normalize)
{
if (period <= Mathf.Epsilon) { return 0f; } // catch a period of 0
float cycles = Time.time / period;
float sin = Mathf.Sin(cycles * tau);
if (!normalize) { return sin; }
else { return (sin / 2f) + .5f; }
}
}