当前位置:网站首页>Unity uses navmesh to realize simple rocker function
Unity uses navmesh to realize simple rocker function
2022-07-27 01:24:00 【Calm nine】
Unity Use NavMesh Realize simple rocker function
introduction
In everyday unity Project under development , We often encounter the problem of character movement , Here we make a suggested joystick function to control the movement of the character . Requirements are as follows :
- Is the rocker in UI Click anywhere blocked , Rocker appears , And use this as the origin to drag .
- The character moves towards the rocker .
- The scene has boundaries , There are obstacles .
Implementation scheme
scene
Scene use navmesh Bake , About the baking method of the scene , There are many on the Internet , I'm just going to go over it here . Obstacle mounting NavMeshObstacle, Adjustable size .
rocker
For the convenience of future use , We need to open several events in the joystick control script : Start moving events , Moving event , Move end event .
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
/// <summary>
/// Virtual rocker
/// </summary>
public class JoyStick : MonoBehaviour
{
[SerializeField]
/// <summary>
/// Center point of rocker
/// Need to be in UI Interface designation
/// </summary>
private Transform _PotTran;
#region Unity Events
/// <summary>
/// Move start event
/// </summary>
[System.Serializable]
public class OnMoveStartHandler : UnityEvent<Vector2> { }
/// <summary>
/// Moving event
/// </summary>
[System.Serializable]
public class OnMoveHandler : UnityEvent<Vector2> { }
/// <summary>
/// Move completion event
/// </summary>
[System.Serializable]
public class OnMoveEndHandler : UnityEvent { }
[SerializeField]
public OnMoveStartHandler OnMoveStart;
[SerializeField]
public OnMoveHandler OnMove;
[SerializeField]
public OnMoveEndHandler OnMoveEnd;
#endregion
/// <summary>
/// The center point of the rocker moves in the area
/// </summary>
private Rect _Rect;
/// <summary>
/// Click the origin position
/// </summary>
private Vector2 _OriginVec;
/// <summary>
/// Whether it's dragging
/// </summary>
private bool _Dragging = false;
void Start()
{
_Rect = transform.GetComponent<RectTransform>().rect;
}
void Update()
{
if (IsPointerOverUI())
{
StopDrag();
return;
}
if (Input.GetMouseButtonDown(0))
{
StartDrag(Input.mousePosition);
}
if (Input.GetMouseButtonUp(0))
{
StopDrag();
}
if (Input.GetMouseButton(0))
{
Drag(Input.mousePosition);
}
}
/// <summary>
/// The center point returns to its original position
/// </summary>
private void BackOrigin()
{
_PotTran.localPosition = Vector3.zero;
}
/// <summary>
/// Set the center point position
/// </summary>
private void SetOriginPos(Vector3 pos)
{
_PotTran.localPosition = pos;
}
/// <summary>
/// Start drag
/// </summary>
/// <param name="pos"></param>
private void StartDrag(Vector2 pos) {
if (!_Dragging)
{
_Dragging = true;
_OriginVec = pos;
OnMoveStart?.Invoke(pos);
}
}
/// <summary>
/// Dragging
/// </summary>
/// <param name="pos"></param>
private void Drag(Vector2 pos) {
if (!_Dragging) {
return;
}
float oldDis = Vector3.Distance(pos, _OriginVec);
//UI The displacement should be greater than a certain value , Modify according to your own requirements
if (oldDis > 0.1f)
{
float newDis = oldDis;
if (newDis > _Rect.width * 0.5f)
{
newDis = _Rect.width * 0.5f;
}
Vector2 gap = (pos - _OriginVec) / oldDis * newDis;
SetOriginPos(gap);
OnMove?.Invoke((pos - _OriginVec).normalized * Time.deltaTime * 3);
}
}
/// <summary>
/// Stop dragging
/// </summary>
private void StopDrag() {
if (_Dragging)
{
_Dragging = false;
BackOrigin();
OnMoveEnd?.Invoke();
}
}
/// <summary>
/// Judge whether the mouse click has UI Under the mouse
/// </summary>
/// <returns></returns>
public bool IsPointerOverUI()
{
PointerEventData eventData = new PointerEventData(EventSystem.current);
eventData.pressPosition = Input.mousePosition;
eventData.position = Input.mousePosition;
List<RaycastResult> list = new List<RaycastResult>();
if (EventSystem.current)
EventSystem.current.RaycastAll(eventData, list);
return list.Count > 0;
}
}
Character control
Here we only realize the movement and pause of the character .
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
/// <summary>
/// role
/// </summary>
public class CharactorAgent : MonoBehaviour
{
/// <summary>
/// agent
/// </summary>
private NavMeshAgent _Agent;
/// Are you moving
/// </summary>
private bool _IsMoving = false;
void Start()
{
_Agent = GetComponent<NavMeshAgent>();
if (!_Agent)
{
_Agent = gameObject.AddComponent<NavMeshAgent>();
}
_Agent.enabled = true;
}
void Update()
{
}
/// <summary>
/// People move
/// </summary>
/// <param name="offset"> Relative displacement </param>
public void Move(Vector3 offset)
{
if (!_Agent.enabled)
{
_Agent.enabled = true;
}
// to turn to , You can add steering animation according to your own needs
transform.forward = offset;
ChangeMove(true);
_Agent.Move(offset);
}
/// <summary>
/// Change the movement status
/// Players' actions can be changed here
/// </summary>
/// <param name="isMove"></param>
public void ChangeMove(bool isMove)
{
if (!_IsMoving && isMove)
{
_IsMoving = true;
}
if (_IsMoving && !isMove)
{
_IsMoving = false;
}
}
/// <summary>
/// Stop moving
/// </summary>
public void StopMove()
{
if (_Agent.enabled)
{
_Agent.ResetPath();
_Agent.isStopped = true;
_Agent.enabled = false;
}
ChangeMove(false);
}
}
The following function of the camera is not done ,unity There are many camera following scripts available .
Main logic
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Main logic
/// </summary>
public class TestService : MonoBehaviour
{
[SerializeField]
private JoyStick _JoyStick;
[SerializeField]
private CharactorAgent _CharactorAgent;
void Start()
{
Canvas canvas = _JoyStick.GetComponentInParent<Canvas>();
RectTransform parentRect = _JoyStick.transform.parent.GetComponent<RectTransform>();
Vector3 oldPos = _JoyStick.transform.localPosition;
_JoyStick.OnMoveStart.AddListener(delegate (Vector2 vec)
{
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRect, vec, canvas.worldCamera, out Vector2 localPos))
{
_JoyStick.transform.localPosition = localPos;
}
});
_JoyStick.OnMove.AddListener(delegate (Vector2 vec)
{
_CharactorAgent.Move(new Vector3(vec.x, 0, vec.y));
});
_JoyStick.OnMoveEnd.AddListener(delegate ()
{
_CharactorAgent.StopMove();
_JoyStick.transform.localPosition = oldPos;
});
}
}
边栏推荐
猜你喜欢

Spark ---- shuffle and partition of RDD

Jenkins--基础--5.2--系统配置--系统配置
![【unity】Unity界面scene视图[1]](/img/5a/c34ff09ef1ddba4b65c7873775c251.png)
【unity】Unity界面scene视图[1]

快来帮您一分钟了解移动互联网

Website log collection and analysis process

【无标题】
![[CTF attack and defense world] questions about backup in the web area](/img/af/b78eb3522160896d77d9e82f7e7810.png)
[CTF attack and defense world] questions about backup in the web area

Li Hongyi machine learning (2017 Edition)_ P6-8: gradient descent

Surrounded area

IDEA导入外部项目时pom文件的依赖无效问题解决
随机推荐
Code merging of centralized version control tools
[CTF attack and defense world] questions about backup in the web area
Wu Enda's in-depth learning series teaching video learning notes (I) -- logistic regression function for binary classification
markdown
2. Wrong odometer
4. Root user login
Play guest cloud brush machine 5.9
AssetBundle遇到的坑
李宏毅机器学习(2017版)_P13:深度学习
Compile Darknet under vscode2015 to generate darknet Ext error msb3721: XXX has exited with a return code of 1.
x 的平方根
吴恩达深度学习系列教学视频学习笔记(一)——用于二分类的logistic回归函数
DataNode Decommision
Li Hongyi machine learning (2017 Edition)_ P14: back propagation
Jenkins--基础--04--安装中文插件
Li Hongyi machine learning (2017 Edition)_ P5: error
Doris or starrocks JMeter pressure measurement
Naive Bayes Multiclass训练模型
集中式版本控制工具代码合并问题
1. 众数
