当前位置:网站首页>Unity—四元数、欧拉角API+坐标系统
Unity—四元数、欧拉角API+坐标系统
2022-08-01 23:55:00 【小小数媒成员】
每日一句:做喜欢的事是没有截止日期的
补上这两天的~
目录
练习:如果移出屏幕外,停止运动,(可返回);移出屏幕上边界,下边界返回,移出左边界,右边界返回
练习:计算物体右前方30度,10m远的坐标
public Vector3 vect;
void Update()
{
Debug.DrawLine(this.transform.position, vect);
vect = this.transform.position + Quaternion.Euler(0, 30, 0) *this.transform.rotation * new Vector3(0, 0, 10);
}
this.transform.position + 把向量移到当前物体位置
*this.transform.rotation * new Vector3(0, 0, 10)向量随当前物体的旋转而旋转
练习:计算爆炸点到玩家两个切点坐标
已知:玩家半径Radius,玩家、炸弹位置
思路:1.计算玩家到爆炸点方向,半径长向量
2.根据夹角旋转该向量
脚本给炸弹,本身就知道炸弹位置了
(两个物体没关系怎么找,用标签找)
public string playerTag = "Player";
private Transform playerTF;
private float radius;
void Start()
{
GameObject playerGO = GameObject.FindWithTag(playerTag);//获取玩家的游戏对象
playerTF = playerGO.transform;
radius = playerGO.GetComponent<CapsuleCollider>().radius;
}
private Vector3 leftTangent,rightTangent;
void Update()
{
Vector3 playerToExplosion = this.transform.position - playerTF.position;
Vector3 playerToExplosionDirection = playerToExplosion.normalized * radius;
float angle = Mathf.Acos(radius / playerToExplosion.magnitude) * Mathf.Rad2Deg;
leftTangent = Quaternion.Euler(0, -angle, 0) * playerToExplosionDirection + playerTF.position;
rightTangent = Quaternion.Euler(0, angle, 0) * playerToExplosionDirection + playerTF.position;
Debug.DrawLine(this.transform.position, leftTangent, Color.red);
Debug.DrawLine(this.transform.position, rightTangent, Color.red);
}
效果展示:
sqrMagnitude 模长的平方 若只比较两向量长度,用sqrMagnitude,比magnitude少开方了,节省性能
Vector3.OrthoNormalize(ref Vector3 normal,ref Vector3 tangent,ref Vector3 binormal)
将向量标准化,返回tangent、binormal与normal是垂直关系
//投影测试ProjectOnPlane
public Transform t1;
public Vector3 planeNorm;
private void Update()
{
Vector3 result = Vector3.ProjectOnPlane(t1.position, planeNorm);
Debug.DrawLine(Vector3.zero, result, Color.red);
Debug.DrawLine(Vector3.zero, t1.position);
}
将当前物体移动(要过程)(欧拉角)
//匀速移动,能达到目标点
this.transform.position=Vector3.MoveTowards(this.transform.position,new Vector3(0,0,10),0.1f);(起点,终点,速度)
//先快后慢,不能到达目标点(无限接近)//终点、比例固定
this.transform.position=Vector3.Lerp(this.transform.position,new Vector3(0,0,10),0.1f);
//自然移动
public AnimationCurve curve;//动画曲线
private float x;
public float duration=3;//持续时间(3秒钟到达终点)
private void Update()
{ x+=Time.deltaTime/duration;//累加每帧消耗的时间
this.transform.position=Vector3.Lerp(Vector3zero,
new Vector3(0,0,10),curve.Evaluate(x));
四元数API
四元数—>欧拉角
Quaternion qt=this.transform.rotation;
Vector3 euler=qt.eulerAngles;
轴/角旋转
Quaternion Quaternion.AngleAxis(float angle,Vector3 axis);(角,轴向)
this.transform.rotation=Quaternion.AngleAxis(50,Vector3.up);
(等同Quaternion.Euler(0,50,0);)
//注视旋转(z轴)
public Transform tf;//当前物体注视tf旋转
Vector3 dir=tf.position-this.transform.position;//当前物体注视tf旋转
this.transform.rotation=Quaternion.LookRotation(dir);//可以分成多帧
(this.transform.LookAt(tf);)//一帧就变了
//差值旋转Lerp,匀速旋转Quaternion.RotateTowards
Quaternion dir=Quaternion.LookRotation(tf.position-this.transform.position);
this.transform.rotation=Quaternion.Lerp(this.transform.rotation,dir,0.1f);
Quaternion dir = Quaternion.Euler(0, 90, 0); void Update() { this.transform.rotation = Quaternion.Lerp(this.transform.rotation, dir, 0.1f); //如果当前旋转角度,接近目标旋转角度 if(Quaternion.Angle(this.transform.rotation,dir)<1) { this.transform.rotation = dir; } }
//x轴注视旋转
this.transform.right=tf.position-this.transform.position;
想慢慢转—>凑Lerp—>四元数
Quaternion dir=Quaternion.FormToRotation
(Vector3.right,tf.position-this.transform.position);
练习:根据用户输入的方向旋转角色,并向前移动
public float moveSpeed = 3;
public float rotateSpeed = 2;
private void Update()
{
float hor = Input.GetAxis("Horizontal");
float ver = Input.GetAxis("Vertical");
Quaternion dir = Quaternion.LookRotation(new Vector3(hor, 0, ver));
this.transform.rotation = dir;
this.transform.rotation = Quaternion.Lerp(this.transform.rotation, dir, Time.deltaTime * rotateSpeed);
if(hor!=0||ver!=0)
this.transform.Translate(0, 0, Time.deltaTime * moveSpeed);
}
坐标系统
Unity坐标系
World Space
世界(全局)坐标系:整个场景的固定坐标
作用:在游戏场景中表示每个游戏对象的位置和方向
Local Space
物体(局部)坐标系:每个物体独立的坐标系,原点为模型轴心点,随物体移动或旋转而改变
作用:表示物体间相对位置与方向
Screen Space
屏幕坐标系:以像素为单位,屏幕左下角为原点(0,0),右上角屏幕宽,高度,z为到相机的距离
作用:表示物体在屏幕中的位置
Viewport Space
视口(摄像机)坐标系:屏幕左上方原点为(0,0),右上角为(1,1),z为到相机的距离
作用:表示物体在摄像机中的位置
坐标系转换
Local Space—>World Space
transform.forward在世界坐标系中表示物体在正前方
transform.right在世界坐标系中表示物体在正右方
transform.up在世界坐标系中表示物体在正上方
transform.TransformPoint 转换点,受变换组件位置、旋转和缩放影响
transform.TransformDirection 方向,受变换组件旋转影响
transform.TransformPoint 向量,受变换组件旋转和缩放影响
World Space—>Local Space
transform.InverseTransformPoint;转换点,受变换组件位置,旋转和缩放影响
transform.InverseTransformDirection;方向,受变换组件旋转影响
transform.InverseTransformVector;转换点,受变换组件旋转和缩放影响
World Space<—>Local Space
Camera.main.WorldToScreenPoint将点从世界坐标系转换到屏幕坐标系中
Camera.main.ScreenToWorldPoint将点从屏幕坐标系转换到世界坐标系中
World Space<—>Viewport Space
Camera.main.WorldToViewportPoint将点从世界坐标系转换到视口坐标系中
Camera.main.ViewportToWorldPiont将点从屏幕坐标系转换到世界坐标系中
练习:如果移出屏幕外,停止运动,(可返回);移出屏幕上边界,下边界返回,移出左边界,右边界返回
public float moveSpeed = 3;
private Camera mainCamera;
private void Start()
{
mainCamera = Camera.main;
}
private void Update()
{
float hor = Input.GetAxis("Horizontal");
float ver = Input.GetAxis("Vertical");
hor *= moveSpeed * Time.deltaTime;
ver*= moveSpeed * Time.deltaTime;
Vector3 screenPoint = mainCamera.WorldToScreenPoint(this.transform.position);
//如果超过屏幕,停止运动
//如果到了最左边 并且还想向左运动 或者到了最右边并且还想向右运动
if (screenPoint.x <= 0 && hor < 0 || screenPoint.x >= Screen.width && hor > 0)
hor = 0;
//上出,下进
if (screenPoint.y > Screen.height)
screenPoint.y = 0;
//下出,上进
if (screenPoint.y < 0)
screenPoint.y = Screen.height;
this.transform.position = Camera.main.ScreenToWorldPoint(screenPoint);
this.transform.Translate(hor, 0, ver);
}
边栏推荐
猜你喜欢
[Camp Experience Post] 2022 Cybersecurity Summer Camp
Work for 5 years, test case design is bad?To look at the big case design summary
EasyExcel的简单读取操作
ES中SQL查询详解
CDH6 Hue to open a "ASCII" codec can 't encode characters
如何重装Win11?一键重装Win11方法
使用Jenkins做持续集成,这个知识点必须要掌握
Building a cloud-native DevOps environment
security跨域配置
Artifact XXXwar exploded Artifact is being deployed, please wait...(已解决)
随机推荐
ELK log collection
在MySQL中使用MD5加密【入门体验】
Share an interface test project (very worth practicing)
辛普森悖论
security CSRF漏洞保护
2022 6th Strong Net Cup Part WP
color transparency parameter
@Transactional注解在类上还是接口上使用,哪种方式更好?
Zadig 面向开发者的自测联调子环境技术方案详解
recursion: method calls itself
Deep Learning Fundamentals - Numpy-based Recurrent Neural Network (RNN) implementation and backpropagation training
DOM 基础操作
security 会话并发管理
【图像融合】基于加权和金字塔实现图像融合附matlab代码
程序员还差对象?new一个就行了
Win11内存管理错误怎么办?
@Resource和@Autowired的区别
Bean的生命周期
Excel文件读写(创建与解析)
Is TCP reliable?Why?