目录
[修改 transform.up 的行为和影响](#修改 transform.up 的行为和影响)
获取相机可视范围的世界坐标(2D)
// 获取摄像机到z=0平面的距离
float zDistance = Mathf.Abs(Camera.main.transform.position.z);
Vector3 bottomLeft = Camera.main.ViewportToWorldPoint(new Vector3(0, 0, zDistance));
Vector3 topRight = Camera.main.ViewportToWorldPoint(new Vector3(1, 1, zDistance));
// 计算转换后的中心点和大小等
Vector2 center = (topRight + bottomLeft) / 2;
Vector2 size = new Vector2(topRight.x - bottomLeft.x, topRight.y - bottomLeft.y);
视口转世界坐标和屏幕转世界坐标的区别:
屏幕转世界坐标
屏幕坐标系统是以像素为单位,原点(0,0)通常位于屏幕的左上角,x轴向右增加,y轴向下增加。屏幕坐标表示的是屏幕上每一个像素的位置。
在Unity中,可以使用Camera.ScreenToWorldPoint()
方法将屏幕坐标转换成世界坐标。这通常用于鼠标点击或触摸屏事件,因为这些输入事件提供的坐标基于屏幕像素。
比如说将鼠标在屏幕上点击的位置转化为世界坐标:
Vector3 screenPosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, distanceFromCamera);//这个距离是根据自己想要检测的目标所在的平面而决定的
Vector3 worldPosition = Camera.main.ScreenToWorldPoint(screenPosition);
视口转屏幕坐标
视口坐标系统用的是一种从0到1的范围,其中(0,0)表示视口的左下角,(1,1)表示右上角。视口坐标与屏幕的实际分辨率无关,因此更加灵活和通用。
在Unity中,Camera.ViewportToWorldPoint()
方法被用来将视口坐标转换为世界坐标。这对于定位相对于摄像机视图百分比位置的对象非常有用。
应用:将可视范围转化为世界坐标,得到在世界坐标中的可视范围,可用于参与一些检测啥的
视口转屏幕结合3D数学实现可视范围的怪物生成
cs
private void CalculateCurrentProducePosition()
{
// 获取摄像机到z=0平面的距离
float zDistance = Mathf.Abs(Camera.main.transform.position.z);
bottomLeft = Camera.main.ViewportToWorldPoint(new Vector3(0, 0, zDistance));
topRight = Camera.main.ViewportToWorldPoint(new Vector3(1, 1, zDistance));
// 计算中心点和大小等
center = (topRight + bottomLeft) / 2;
size = new Vector2(topRight.x - bottomLeft.x, topRight.y - bottomLeft.y);
}
private void GenerateEnemy()
{
float radiu =size.x/2.0f;
float angle = Random.Range(0, 359);
//一定要加上中心点啊,3D数学!
Vector3 generateDir = Quaternion.Euler(0, 0, angle) * new Vector3(0,1f,0) * radiu + new Vector3(center.x, center.y, 0); //圆上的一个随机点
GamePoolManager.Instance.TryGetPoolItem("OrdinaryZombies", generateDir, Quaternion.identity);
}
transform.up游戏对象的方向问题
修改 transform.up
是一个改变游戏对象朝向的有效方式,它通过调整对象的旋转来确保其"上"方向与你指定的向量对齐
这个用于比方说子弹的弹头旋转啥的就非常合适,并且效果出奇
在Update中:
transform.up = (target.transform.position - transform.position); //旋转方向朝向指向敌人的向量的方向,(同时也夹杂着这个方向的旋转)
transform.Translate(transform.up * moveSpeed * Time.deltaTime, Space.World);
Space.World是重点,为什么呢,参考下图
不填Space.World,就默认Space.Self,朝向就会变得非常的奇怪
其实还有一种不用Translate的写法:
transform.up = (target.transform.position-transform.position);
transform.position = transform.position+transform.upTime.deltaTimemoveSpeed;
这种写法其实更加不容易出错
关于transform.up的知识点:
修改 transform.up
的行为和影响
-
修改旋转 :设置
transform.up
会自动调整游戏对象的旋转,以使其上方向与你指定的向量对齐。这一修改涉及到四元数的计算,Unity内部会自动处理这些计算。 -
内部实现 :在Unity的内部实现中,当你设置
transform.up
时,实际上是在调用Quaternion.LookRotation
方法。这个方法将新的向上向量和前向向量(如果未明确指定,则使用当前前向向量)作为参数,计算出新的旋转。 -
向量归一化 :当你设置
transform.up
时,Unity会自动归一化你提供的向量。归一化是将向量的长度标准化为1的过程,这对于方向向量是必要的,因为方向向量的长度不应影响对象的旋转
对比Vector3.up:(Unity手册中 关于transform.up的解释)
世界空间中变换的绿轴。
操作游戏对象在世界空间中变换的 Y 轴(绿轴)上的位置。与 Vector3.up 不同,Transform.up 在移动游戏对象的同时,还考虑其旋转。
旋转游戏对象时,表示游戏对象的 Y 轴的绿色箭头也会改变方向。Transform.up 沿绿色箭头所在的轴 (Y) 移动游戏对象。
要在沿 Y 轴移动 GameObject 时忽略旋转,请参阅 Vector3.up。
C#抽象类和接口的区别
接口是 用于规范不同对象的共同行为
而当一个基类变成抽象类的时候,子类去继承,那他们的父类就都是同一个类型了,所以本质上的区别就体现在了这里
也就是说当我们不知道这些子类是否要继承不同的基类的时候,我们通常就可以使用接口来进行规范