ui界面的自适应分辨率
在canvas对象中添加这个组件
选择scale with screen size,调整一下即可
通过控制虚拟摇杆移动人物
虚拟摇杆
public class VJHandler : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler
{
private Image jsContainer;
private Image joystick;
public Vector3 InputDirection;
public static bool isMove;
void Start()
{
isMove = false;
jsContainer = GetComponent<Image>();
joystick = transform.GetChild(0).GetComponent<Image>(); //this command is used because there is only one child in hierarchy
InputDirection = Vector3.zero;
}
public void OnDrag(PointerEventData ped)
{
isMove = true;
Vector2 position = Vector2.zero;
//获取输入方向
RectTransformUtility.ScreenPointToLocalPointInRectangle
(jsContainer.rectTransform,
ped.position,
ped.pressEventCamera,
out position);
position.x = (position.x / jsContainer.rectTransform.sizeDelta.x);
position.y = (position.y / jsContainer.rectTransform.sizeDelta.y);
float x = (jsContainer.rectTransform.pivot.x == 1f) ? position.x * 2 + 1 : position.x * 2 - 1;
float y = (jsContainer.rectTransform.pivot.y == 1f) ? position.y * 2 + 1 : position.y * 2 - 1;
InputDirection = new Vector3(x, y, y);
InputDirection = (InputDirection.magnitude > 1) ? InputDirection.normalized : InputDirection;
//限定Joystick能移动的区域
joystick.rectTransform.anchoredPosition = new Vector3(InputDirection.x * (jsContainer.rectTransform.sizeDelta.x / 3)
, InputDirection.y * (jsContainer.rectTransform.sizeDelta.y) / 3);
}
public void OnPointerDown(PointerEventData ped)
{
OnDrag(ped);
}
public void OnPointerUp(PointerEventData ped)
{
InputDirection = Vector3.zero;
joystick.rectTransform.anchoredPosition = Vector3.zero;
isMove = false;
GameObject.Find("模型").GetComponent<Animator>().SetFloat("speed", 0);
}
}
这里是直接贴上了大佬的代码,然后修改了一点内容
需要继承 IDragHandler, IPointerUpHandler, IPointerDownHandler这三个类,然后重写他们的方法
大佬帖子里的是2d的,但我需要移动的模型是3d的,所以需要在InputDirection = new Vector3(x, y, y);
这里把z轴的值也变成y值
然后挂载在虚拟摇杆的对象里即可
人物
public class MovePlayers : MonoBehaviour
{
private float moveSpeed = 10f;
public VJHandler jsMovement;
private Vector3 direction;
private float xMin, xMax;
CharacterController character;
void Update()
{
if (VJHandler.isMove)
{
GameObject.Find("Ameng").GetComponent<Animator>().SetFloat("speed",1);
direction = jsMovement.InputDirection; //InputDirection can be used as per the need of your project
if (direction.magnitude != 0)
{
transform.position += direction * moveSpeed;
transform.position = new Vector3(transform.position.x, -0.5492204f, transform.position.z);//to restric movement of player
}
direction += Vector3.down * 10 * Time.deltaTime;
Vector3 vec = new Vector3(-direction.x,0, -direction.z);
Quaternion newRotation = Quaternion.LookRotation(vec);
GameObject.Find("模型").transform.rotation = Quaternion.RotateTowards(GameObject.Find("模型").transform.rotation,newRotation,100);
}
}
void Start()
{
character = GetComponent<CharacterController>();
}
}
这里也是贴了前面的大佬的帖子再做了适当的修改,当移动的时候需要让人物的面向也和移动的方向保持一致
Vector3 vec = new Vector3(-direction.x,0, -direction.z);
Quaternion newRotation = Quaternion.LookRotation(vec);
GameObject.Find("模型").transform.rotation = Quaternion.RotateTowards(GameObject.Find("模型").transform.rotation,newRotation,100);
也就是上面的这串代码
然后挂载到人物对象上,把虚拟摇杆的代码组件挂载到人物的代码组件里即可
摄像机的跟踪
private Vector3 offset;
public Transform player;
void Start()
{
offset = player.position - transform.position;
}
void Update()
{
transform.position = Vector3.Lerp(transform.position, player.position - offset, Time.deltaTime * 5);
Quaternion rotation = Quaternion.LookRotation(player.position - transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * 3f);
}
这个是贴了另一个大佬的帖子,这个没有修改,挂载到摄像机后把模型的transform挂到player上即可实现摄像机跟踪移动的效果
win上模型正常但真机测试时模型出现频闪现象
原因
摄像机的clipping camera的near太小了,摄像机渲染不到太远的模型材质,需要调大一点
解决办法
首先
然后
把安卓和win上的设置调成一样的即可
模型原地动作
模型导入后,设置humanid
然后在animation里
不要烘焙第三个xz的那个然后apply就可以了
总结:无情的cv工程师
2021.7.17更新
有关虚拟摇杆的补充
后面小弟用了新的虚拟摇杆的框架
为啥用新的虚拟摇杆,是因为在后面实现的功能里需要能够控制摄像机去旋转人物,然后在旋转了人物之后还能在当前的视角里进行相对移动
如果还是用前面的话,由于使用的是charactercontroller组件,他只能用simplemove和move去控制人物移动,但是这个移动只能通过vector3去控制,小弟目前的能力还无法通过简单的vector3区进行相对移动,所以就只能放弃原有的虚拟摇杆,用新的了
新的实现方法是通过刚体的moveposition方法完成的,这个可以获得物体当前的位置然后进行相对移动,从而实现我们要的功能
但是新的框架实现摇杆的时候出了新的问题,那就是灵敏度的问题
在编辑器的环境下灵敏度是正常的,但是一打包到安卓环境去测试的时候,就会变得特别的灵敏,动一下就会移动到很偏的地方,之前一直以为是不兼容的问题,也没有去理过他,现在觉得这个问题还是一定要解决的,所以我就把原有的虚拟摇杆的代码和现在新的框架的代码去比较了一下,一开始我以为是在player里面去找答案,但是后面觉得应该不是,应该还是虚拟摇杆的代码里出了问题,在一番对比之后,发现了原有的代码里比新的代码多了一个对xy值的优化,那就是标准化,之前其实也有研究过原先虚拟摇杆的代码,但是当时对unity的使用还不够熟练,还不是太理解, 现在回去看的时候,由于之前看到很多人都在用标准化去约束和规定一些变量,才明白现在的代码之所以太灵敏了可能就是因为没有进行标准化的流程,所以我就在虚拟摇杆获得摇杆的xy值的时候对他进行了标准化
就是上面这行,打包运行后发现终于正常了~
继续加油吧~