当前位置:网站首页>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);
}边栏推荐
猜你喜欢

oozie startup error on cdh's hue, Cannot allocate containers as requested resource is greater than maximum allowed

cdh6打开oozieWeb页面,Oozie web console is disabled.

GIF制作-灰常简单的一键动图工具

Thinkphp 5.0.24变量覆盖漏洞导致RCE分析

Share an interface test project (very worth practicing)

Leetcode 129求根节点到叶节点数字之和、104二叉树的最大深度、8字符串转换整数(atoi)、82删除排序链表中的重复元素II、204二分查找、94二叉树的中序遍历、144二叉树的前序遍历

工作5年,测试用例都设计不好?来看看大厂的用例设计总结

Wincc报表教程(SQL数据库的建立,wincc在数据库中保存和查询数据,调用Excel模板把数据保存到指定的位置和打印功能)

很多人喜欢用多御安全浏览器,竟是因为这些原因

SphereEx苗立尧:云原生架构下的Database Mesh研发实践
随机推荐
Secondary Vocational Network Security Competition B7 Competition Deployment Process
ES中SQL查询详解
【MySQL系列】MySQL数据库基础
Bean的生命周期
架构基本概念和架构本质
recursion: method calls itself
如何进行数据库备份
TCP 可靠吗?为什么?
企业防护墙管理,有什么防火墙管理工具?
Cash Ⅱ LeetCode_518_ change
【MySQL系列】MySQL索引事务
Excel表格数据导入MySQL数据库
windows sql server 如何卸载干净?
根本上解决mysql启动失败问题Job for mysqld.service failed because the control process exited with error code
Docker实践经验:Docker 上部署 mysql8 主从复制
带你搞懂MySQL隔离级别,两个事务同时操作同一行数据会怎样?
【Leetcode】479. Largest Palindrome Product
Flink Yarn Per Job - 提交流程一
如何重装Win11?一键重装Win11方法
Flink学习第四天——完成第一个Flink 流批一体案例