【校招VIP】Unity 原神人物移动和镜头处理

10月18日 收藏 0 评论 0 产品经理

【校招VIP】Unity 原神人物移动和镜头处理

转载声明:文章来源:https://blog.csdn.net/qq_38913715/article/details/128874912

1.每帧都处理的地方 不要用 SetTrigger

为什么呢?

你肯定会希望 SetTrigger run 就跑步 SetTrigger stop 就停止

但事实并非如此

SetTrigger 会在下一帧自动设置回去

而你移动肯定是每帧都在 SetTrigger 所以人物移动会抽搐

最好的办法是 设置float

2.分析原神的镜头

界面左侧负责控制人物移动

界面右侧负责控制视角

人物的移动方向 和 人物朝向没有关系。只和镜头方向有关系。

v.x = this.joystick.Horizontal;
v.z = this.joystick.Vertical;
if (v.x == 0 && v.z == 0)
{
this.animator.SetFloat("runfloat", 0.0f);
return;
}
else
{
this.animator.SetFloat("runfloat", 0.2f);
}
Vector3 startV3 = new Vector3(this.freeLook.transform.position.x, 0, this.freeLook.transform.position.z);
Vector3 endV3 = new Vector3(this.transform.position.x, 0, this.transform.position.z);
Vector3 n = (endV3 - startV3).normalized;
镜头到角色的方向
this.transform.forward = n;
临时让人物朝向这个方向,方便后面计算
Vector3 v3 = this.transform.forward * v.z + this.transform.right * v.x;
前方向 * 摇杆的 y + 右方向 * 摇杆的 x
this.transform.LookAt(this.transform.position + v3);
this.transform.position += v3 * 0.03f;

3.右边的镜头用的是freelook镜头

ps.本来想计算角度啥的

后来志神提醒一下就解决了 感谢志神!

一点优化小细节

Vector3.sqrMagnitude 是指长度的平方,也就是Vector3.magnitude的平方

计算向量大小的平方会比计算向量的大小要快很多,因为向量的大小由勾股定理得出,所以有开方操作,如果只是单纯的比较两个向量的大小,可以使用sqrMagnitude会快很多。

4.镜头让障碍物挡住了咋整?

添加一个这个

这三个就是遇到障碍物 不同的处理方式

第一个 就是简单的把 镜头移动到障碍物前面 向着镜头的 Forward 方向移动

第二个 是保持镜头高度 也就是说 距离障碍物越近 人物变的越大

第三个 保持镜头距离 但是会改变角度 相当于把摄像头挤上去了

可以看这个地方

https://cloud.tencent.com/developer/article/2080742

总之非常重要的功能

如果左右移动 你会发现 角色是绕圈的

因为你的移动方向和镜头是90度 相当于画圈了

可以参考下这个

Lock To Target On Assign:本地空间,相机被激活或target赋值时的相对位置。

Lock To Target With World Up:本地空间,保持相机y轴朝上,yaw和roll为0。

Lock To Target No Roll:本地空间,锁定到目标物体,roll为0。

Lock To Target:本地空间,锁定到目标物体

World Space:世界空间

Simple Follow With World Up:相对于目标的位置,使用相机的本地坐标系,保持相机y轴朝上

获得组件用 GetCinemachineComponent

这个插件还有一个例子可以学习下

仔细观察

原神双指捏合 可以控制镜头

怎么办

非常简单

控制freelook镜头的地方 判断下 如果是两指就不滑动屏幕了

if (JoyCube.Use.UpdateAndGetFingers().Count == 2)
{
return;
}

下面是动态改变

var fingers = Use.UpdateAndGetFingers();
Cinemachine.CinemachineFreeLook.Orbit o = this.freeLook.m_Orbits[1];
o.m_Radius *= Lean.Touch.LeanGesture.GetPinchScale(fingers);
Cinemachine.CinemachineFreeLook.Orbit o1 = new Cinemachine.CinemachineFreeLook.Orbit(o.m_Height, o.m_Radius);
this.freeLook.m_Orbits[1] = o1;

直接改属性是不行的 需要创建新的 Orbit 并赋值回去 不然不起作用

好 现在就实现了原神的基本镜头了

对了 捏合状态用的插件是 Lean Touch

非常方便的插件

判断捏合只需要几句话

public static Lean.Touch.LeanFingerFilter Use = new Lean.Touch.LeanFingerFilter(true);
var fingers = Use.UpdateAndGetFingers();
LeanGesture.GetPinchScale(fingers)

滑动屏幕大概是这样的 (草稿)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TouchTest : MonoBehaviour
{
public Cinemachine.CinemachineFreeLook look;
private bool drag = false;
private float startY = 0;
// Update is called once per frame
private float lastx = 0;
private float lasty = 0;

void Update()
{
if (JoyCube.Use.UpdateAndGetFingers().Count == 2)
{
return;
}

if (this.isClick())
{
this.drag = true;
this.startY = look.m_YAxis.Value;
this.lasty = Input.mousePosition.y;
this.lastx = Input.mousePosition.x / Screen.width;
}
if (Input.GetMouseButtonUp(0))
{
this.drag = false;
}
if (this.drag)
{
float pery = (this.lasty - Input.mousePosition.y) / Screen.height;
look.m_YAxis.Value = this.startY + pery;
float perx = Input.mousePosition.x / Screen.width;
look.m_XAxis.Value = -360.0f * (this.lastx - perx);
this.lastx = perx;
}
}

private bool isClick()
{
if (Input.GetMouseButtonDown(0))
{
if (UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject())
{
// Debug.Log("点到了ui");
return false;
}
return true;
}
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
{
if (UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
{
Debug.Log("Touched the UI");
}
}
return false;
}
}

Damping 是干啥的呢

这是控制镜头恢复的速度

如果是0 那么镜头就立即移动

数值越大 镜头恢复越慢

这个是控制镜头偏移的 好像越肩视角用这个

镜头阻尼

选择这个会显示辅助线

但是 你必须展开 Aim , 不然他不会起作用。

细心的你 一定会发现 X Axis 的 value 永远是0

原神那种 一上来 角度固定在后背的 根本做不到

这是为啥呢?

官方给出了答案

就是你的binding mode 需要换一下

你会发现 上面的界面改变了

这样你就可以设置value了

还有一个功能 需要一键回归角度

y的value 非常有意思

0就是bottom 0.5就是middle 1就是top

和你设置的height没关系

你middle再高 也是0.5

一般用

然后这个有一个特点 就是一开始镜头的位置是相对固定的

所以一开始的时候 要让player的rotation是0

这样 look free的 m_XAxis 的 0 和 rotation的0 是 同样的方向

方便我们后面做reset镜头

C 0条回复 评论

帖子还没人回复快来抢沙发