矢量计算公式,ab+bc=ac,a指向c
ab-ac=ab+ca=cb,c指向b,减数指向被减数。
矢量计算公式,ab+bc=ac,a指向c
ab-ac=ab+ca=cb,c指向b,减数指向被减数。
记录踩的一个小坑
Vector.Angle返回0~180,不会为负数。
//这种写法有问题
float k = mousePos.x > transform.position.x ? Vector3.Angle(Vector3.up, transform.position - mousePos) : Vector3.Angle(Vector3.up, mousePos - transform.position);
//这种写法ok
float k = mousePos.x > transform.position.x ? -Vector3.Angle(mousePos - transform.position, Vector3.up) : Vector3.Angle(Vector3.up, mousePos - transform.position);
最后的UI 金币提示器
新创一个canvas来控制层级 没设一个canvas 都要改成camera
文本框与父物体上下左右对齐
才发现改了锚点之后坐标也会改 原来是根据锚点为原点
枪口随着鼠标旋转
脚本
获取旋转 鼠标与枪口所指位置的连线的夹角
获取鼠标位置 因为canvas有缩放 所以涉及到screentoworldpoint 把屏幕坐标转为世界坐标的方法不好在这用
UGUI有方法 拿到canvas与camera 在再update里给个变量接受传出来的坐标
算夹角 用该方法 先获得z(旋转) 夹角正负判断 Vector3.up是该gameObjects所指向的向量
再进行旋转 localRotation 全部放入代码库
给所有枪都挂上 拖的是90canvas
我理解的代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//实现枪炮跟随鼠标移动
public class GunFollow : MonoBehaviour
{
public RectTransform UGUICanvas;//之所以将RectTransform类型命名为画布,是因为我们需要得到坐标,有需要我们看懂代码指的是什么
public Camera mainCamera;
private void Update()
{
//本地坐标转换位世界坐标
Vector3 mousePos;
RectTransformUtility.ScreenPointToWorldPointInRectangle(UGUICanvas, new Vector2(Input.mousePosition.x, Input.mousePosition.y), mainCamera, out mousePos);
//判断z轴位置的正负,分清左右
//屏幕左下角(0,0)右上角是(width,height)
float z;
if(mousePos .x>transform .position.x)//鼠标点在炮塔的中线右边(按照预期炮塔向右转动)
{
z = -Vector3.Angle(Vector3.up, mousePos - transform.position);
//之所以要添加 - ,是因为在炮塔的角度测试中,向右转,z轴是变成负数的
//Vector3.Angle(Vector3.up, mousePos - transform.position),而这一句意思是炮塔向前方转动,并由炮塔所在位置指向鼠标位置。
//Angle在API介绍文档中永远大于0而小于180,所以要在整个语句之前加上 - 再赋值给z轴。
}else
{
z = Vector3.Angle(Vector3.up, mousePos - transform.position);
}
//子物体的旋转跟随父物体:炮塔的旋转跟随父物体2Gun,3Gun,...
transform.localRotation = Quaternion.Euler(0, 0, z);
}
}
哈啰//把源代码简化
using UnityEngine; public class NewBehaviourScript : MonoBehaviour { public RectTransform UGUICanvans; public Camera mainCamera; void Update() { Vector3 mousePos; RectTransformUtility.ScreenPointToWorldPointInRectangle(UGUICanvans, new Vector2(Input.mousePosition.x, Input.mousePosition.y), mainCamera, out mousePos); transform.localRotation = Quaternion.Euler(0, 0,mousePos.z > transform.position.x ? -Vector3.Angle(Vector3.up, mousePos - transform.position) : Vector3.Angle(Vector3.up, mousePos - transform.position)); } }
//鼠标位置转换成画布上的世界坐标
RectTransformUtility.ScreenPointTo WorldPointInRectangle(RectTransform,Vector2,Camera,Out Vector3)
//返回的角度是两个向量之间的无符号角度。这意味着使用两个向量之间的两个可能角度中的较小者。结果永远不会大于180度
Vector3.Angle(vector3 from,vector to)
RectTransformUtility.ScreenPointToWorldPointInRectangle(UGUICanvas, new Vector2(Input.mousePosition.x, Input.mousePosition.y), mainCamera, out mousePos);
1.将一个屏幕坐标转化为UGUI上的世界坐标
Vector3.Angle(Vector3.up, mousePos - transform.position);
2.返回两个向量的夹角,永远是较小的那个角,且注意这个3D用的,2D用时要注意Z轴的影响
Vector.Angle返回一个小于180的角度
计算夹角方法
RectTransformUtility.ScreenPointToWorldPointInRectangle(UICanvas, new Vector2(Input.mousePosition.x, Input.mousePosition.y), maincamera, out mousePos);屏幕坐标转化为世界坐标
1.Camera.ScreenToWorldPoint:转变position从屏幕空间到世界空间。屏幕空间以像素为单位定义。屏幕的左下角是(0,0);右上角是(pixelWidth,pixelHight)。z位置是相机的世界单位。
2.Event.mousePosition:鼠标位置。用于EventType.MouseMove和EventType.MouseDrag事件。窗口的左上角返回(0,0)。右下角返回(Screen.width,Screen.height)。
以上两种方法不太适合用于UGUI。
可以用UGUI中已经封装好的的方法:ScreenPointToWorldPoint。
3.public static bool ScreenPointToWorldPointInRectangle(RectTransform rect, Vector2 screenPoint, Camera cam,out Vector3 worldPoint);
参数
{矩形 : RectTransform在里面找到一个点。
凸轮: 相机与屏幕空间位置相关联。
screenPoint : 屏幕空间位置。
worldPoint : 指向世界空间。}
将屏幕空间点转换为位于给定RectTransform平面上的世界空间中的位置。
cam参数应该是与屏幕点相关联的摄像机。对于Canvas中设置为Screen Space - Overlay模式的RectTransform,cam参数应为null。
当从提供PointerEventData对象的事件处理程序中使用ScreenPointToWorldPointInRectangle时,可以使用PointerEventData.enterEventData(用于悬停功能)或PointerEventData.pressEventCamera(用于单击功能)来获取正确的摄像机。这将自动为给定事件使用正确的相机(或null)。
float Angle(Vector2 from, Vector2 to)
可延伸枪随点击旋转,这样可以发布手游来玩
鼠标随着炮弹运动:
1.添加图片,实现炮数功能显示
2.新建一个C#脚本,实现炮弹跟随着鼠标运动
public class GunFollow : monoBchaviour
{
public RectTranform UgUICanvas;//定义一个方向的接收
void Update()
{
UgUICanvas = RectTransformUtility.ScreenPointToWorldPointTnRectangle()
}
}
Camera.ScreenToWorldPoint
Input.MousePosition
因为缩放问题故不用这两个方法获取游戏鼠标位置