using System;
using UnityEngine;
namespace MainEditor
{
/// <summary>
/// 爱的魔力转圈圈
/// 旋转摄像机指定度数
/// </summary>
public class RotationCamera : MonoBehaviour
{
public int weight = 8;
public float radius = 10;
public float power = 0.05f;
public int count=8;
public Action<int> onIndexChanged;
int curAngleIndex;
int curIndex;
int runState;
int stopAnale;
float perimeter;
Vector2 speed;
Vector2 worldPos;
Vector2 origin;
Vector2 direction;
Vector2 screenPos;
Vector3 eulerAngle;
Action[] inputFunctions;
Action[] runStateFunctions;
private void Awake()
{
gameObject.AddComponent<DrawRadius>().radius = radius;
stopAnale = 360 / weight;
origin = transform.position;
perimeter = 2 * Mathf.PI * radius;
inputFunctions = new Action[] { Default, MouseDown, MouseStay, MouseUp };
runStateFunctions = new Action[] { SpeedRoation, FixedAngle };
onIndexChanged = index => Debug.Log(index);
}
private void Update()
{
inputFunctions[GetInputState()].Invoke();
}
void Default()
{
if (runState == -1)
return;
runStateFunctions[runState].Invoke();
}
void Rotation(Vector3 vector )
{
var newValue = vector.z;
var oldValue = transform.localEulerAngles.z;
if (Mathf.Abs(newValue - oldValue) < 0.0001f)
return;
transform.localEulerAngles = vector;
if (newValue > 359)
return;
var v = (int)vector.z / stopAnale;
if (v != curAngleIndex)
{
curAngleIndex = v;
// 0 - 359
int sign = 0;
if(Mathf.Abs(newValue - oldValue) >250)
{
if(newValue<100)// 右
sign = 1;
else if(newValue >250)// 左
sign = -1;
}
else
{
if(newValue >oldValue)//右
sign = 1;
else if(newValue < oldValue)//左
sign = -1;
}
curIndex += sign;
if (curIndex < 0)
curIndex = count - 1;
else if (curIndex >= count)
curIndex = 0;
onIndexChanged?.Invoke(curIndex);
}
}
void SpeedRoation()
{
speed *= Mathf.Pow(0.1f, Time.deltaTime);
if (Mathf.Abs(speed.magnitude) < 10)
{
speed = Vector3.zero;
var angle = transform.localEulerAngles.z;
var v = (int)angle / stopAnale;
// 固定的角度选份量的中间,避免稍微向左偏移就切换到其他角度
eulerAngle = new Vector3(0, 0, v * stopAnale + stopAnale * 0.5f);
runState = 1;
}
else
{
// power 是为了压制或者放大旋转距离。如果半径过小速度过大会飞快旋转
var radian = speed.magnitude * power / perimeter;
var angle = Mathf.Rad2Deg * radian;
Rotation(transform.localEulerAngles + new Vector3(0, 0, angle * Mathf.Sign(direction.x)));
}
}
void FixedAngle()
{
Rotation(Vector3.Slerp(transform.localEulerAngles, eulerAngle, 0.1f));
if (Mathf.Abs(transform.localEulerAngles.z - eulerAngle.z) < 0.1f)
{
Rotation(eulerAngle);
runState = -1;
}
}
void MouseDown()
{
runState = -1;
worldPos = GetWorldPosition();
screenPos = Input.mousePosition;
}
void MouseUp()
{
Vector2 pos = GetWorldPosition();
var delta = worldPos - pos;
direction = ((Vector2)Input.mousePosition - screenPos).normalized;
speed = delta / Time.deltaTime;
worldPos = pos;
runState = 0;
}
void MouseStay()
{
Vector2 pos = GetWorldPosition();
var oldDir = (worldPos - origin).normalized * radius ;
var newDir = (pos - origin).normalized * radius ;
// 求2点间的弧度值
var radian = Mathf.Atan2(newDir.y, newDir.x) - Mathf.Atan2(oldDir.y, oldDir.x);
var angle = Mathf.Rad2Deg * radian;
Rotation(transform.localEulerAngles + new Vector3(0, 0, -angle));
// 因为更新了旋转,所以需要重新获取坐标
worldPos = GetWorldPosition();
}
int GetInputState()
{
if (Input.GetMouseButtonDown(0))
return 1;
if (Input.GetMouseButton(0))
return 2;
if (Input.GetMouseButtonUp(0))
return 3;
return 0;
}
Vector3 GetWorldPosition()
{
return Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
}
}
旋转摄像机
最新推荐文章于 2022-08-28 17:43:00 发布