当前位置:网站首页>Rotating camera
Rotating camera
2022-06-13 00:50:00 【Small fish game development】
using System;
using UnityEngine;
namespace MainEditor
{
/// <summary>
/// The magic of love goes around
/// Rotate the camera by a specified number of degrees
/// </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)// Right
sign = 1;
else if(newValue >250)// Left
sign = -1;
}
else
{
if(newValue >oldValue)// Right
sign = 1;
else if(newValue < oldValue)// Left
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;
// Choose the middle of the portion at a fixed angle , Avoid switching to other angles with a slight shift to the left
eulerAngle = new Vector3(0, 0, v * stopAnale + stopAnale * 0.5f);
runState = 1;
}
else
{
// power To suppress or enlarge the rotation distance . If the radius is too small and the speed is too fast
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 ;
// seek 2 Radian value between points
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));
// Because the rotation is updated , So we need to get the coordinates again
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);
}
}
}
边栏推荐
- 单片机串口中断以及消息收发处理——对接受信息进行判断实现控制
- Comparison of disk partition modes (MBR and GPT)
- Undirected graph -- computing the degree of a node in compressed storage
- STM32 USB Basics
- Druid reports an error connection holder is null
- Win10 home vs pro vs enterprise vs enterprise LTSC
- Assembly language learning
- Set sail
- Static analysis of malicious code
- The grass is bearing seeds
猜你喜欢
Arduino control tm1637 common positive four digit nixie tube
How to solve the duplication problem when MySQL inserts data in batches?
磁盘分区方式对比(MBR与GPT)
Kotlin 协程的作用域构建器 coroutineScope与runBlocking 与supervisorScope,协程同步运行,协程挂掉的时候其他协程如何不被挂掉。
三角波与三角波卷积
Kotlin 协程的四种启动模式
【SCA-CNN 解读】空间与通道注意力:Spatial and Channel-wise Attention
[error] invalid use of incomplete type uses an undefined type
硬(磁)盘(二)
408 true question - division sequence
随机推荐
OceanBase 雄踞墨天轮2021年度中国数据库魔力象限领导者
Some basic design knowledge
[JS] solve the problem that removeeventlistener is invalid after the class listening event from new is bound to this
【SCA-CNN 解读】空间与通道注意力:Spatial and Channel-wise Attention
What are the conditions of index invalidation?
Arduino interrupt
Dynamic planning - good article link
STM32 USB Basics
With a market value of more than trillion yuan and a sales volume of more than 100000 yuan for three consecutive months, will BYD become the strongest domestic brand?
Kotlin 协程,job的生命周期
Three column simple Typecho theme lanstar/ Blue Star Typecho theme
How to solve the duplication problem when MySQL inserts data in batches?
市值破万亿,连续三个月销量破10万,比亚迪会成为最强国产品牌?
Download nail live playback through packet capturing
Sequence table - find main element
Android Weather
高阶极点对于波形的影响
[JS component] browse progress bar
Three kinds of thinking make me reborn
牌好不好无法预料