using System.Collections; using System.Collections.Generic; using DG.Tweening; using UnityEngine; using Sirenix.OdinInspector; namespace Beyond { public class FloatingObject : MonoBehaviour { [TitleGroup("Vertical Movement")] [SerializeField] private float m_height = 1f; [SerializeField] private float m_time = 1f; [SerializeField] private float m_amplitude = 0.2f; [SerializeField] private float m_frequency = 1f; // [SerializeField] private bool m_randomizeOnStart = true; [TitleGroup("X Axis Rotation")] [SerializeField] private float m_xRotationSpeed; [TitleGroup("Y Axis Rotation")] [SerializeField] private float m_yRotationSpeed; [TitleGroup("Z Axis Rotation")] [SerializeField] private float m_zRotationSpeed; enum State { IDLE, GOING_UP, FLOATING, GOING_DOWN }; Vector3 m_startPos; Vector3 m_tmpPos; State m_state; float m_timer = 0f; float m_speed; bool m_isActive; // Start is called before the first frame update void Start() { m_startPos = transform.position; m_frequency *= Random.Range(0.9f, 1.1f); m_height *= Random.Range(0.9f, 1.1f); m_time *= Random.Range(0.9f, 1.1f); m_speed = m_height / m_time; m_isActive = false; SetState(State.GOING_UP); //if (m_randomizeOnStart) // RandomPos(); } void SetState(State s) { switch (s) { case State.IDLE: //enabled = false; break; case State.GOING_UP: break; case State.GOING_DOWN: break; case State.FLOATING: m_tmpPos = transform.position; break; } m_timer = 0f; m_state = s; } public void RandomPos() { var pos = transform.position; pos.y = m_tmpPos.y + Mathf.Sin(Random.Range(0f, 1000f) * m_frequency) * m_amplitude; transform.position = pos; } public void OnStart() { if (!m_isActive) { m_isActive = true; SetState(State.GOING_UP); enabled = true; } } public void OnEnd() { if (m_isActive) { SetState(State.GOING_DOWN); m_isActive = false; } } // Update is called once per frame void Update() { var pos = transform.position; Vector3 newPos = pos; float diff = transform.position.y - m_startPos.y; switch (m_state) { case State.IDLE: break; case State.GOING_UP: if (diff > m_height) { newPos.y = m_startPos.y + m_height; SetState(State.FLOATING); } else { newPos.y += m_speed * Time.deltaTime; transform.position = newPos; } break; case State.GOING_DOWN: if (diff < 0f) { newPos.y = m_startPos.y; transform.position = newPos; SetState(State.IDLE); } else { newPos.y -= m_speed * Time.deltaTime; transform.position = newPos; } break; case State.FLOATING: newPos.y = m_tmpPos.y + Mathf.Sin(m_timer * m_frequency) * m_amplitude; transform.position = newPos; break; } Rotating(); m_timer += Time.deltaTime; } private void Rotating() { transform.Rotate(m_xRotationSpeed * Time.deltaTime, m_yRotationSpeed * Time.deltaTime, m_zRotationSpeed * Time.deltaTime, Space.World); } } }