C#部分
2D虚拟摇杆
先弄个自定义的触发事件,然后给每一个需要触发的事件按钮添加,EventTrigget,需要注意的是这个事件要继承unity的接口,
制作unity的摇杆的话,需要继承unity的的UI接口 IBeginDragHandler, IDragHandler, IEndDragHandler,IPointerClickHandler
首先先定义四个委托
public Action<GameObject, PointerEventData>onBeginDrag
public Action<GameObject, PointerEventData>onDrag
public Action<GameObject, PointerEventData>onEndDrag
public Action<GameObject, PointerEventData>onClick
其次是重写unity继承的四个接口,把每个委托的回调放进去这些接口函数里面,一但满足条件,委托会执行函数回调方法
public void OnBeginDrag(PointerEventData eventData) {
if (onBeginDrag != null)
{
onBeginDrag(gameObject, eventData)
}
}
public void OnDrag(PointerEventData eventData) {
if (onDrag != null)
{
onDrag(gameObject, eventData)
}
}
public void OnEndDrag(PointerEventData eventData) {
if (onEndDrag != null)
{
onEndDrag(gameObject, eventData)
}
}
public void OnPointerClick(PointerEventData eventData){
if (onClick != null)
{
onClick(gameObject, eventData)
}
}
有了这些委托方法之后,如何使用,这个调用方法,会在初始化注册事件,
public static EventTrigger GetEventCallBack(GameObject obj)
{
Event trigger = obj.GetComponent<EventTrigger>()
if (trigger == null)
{
trigger = obj.AddComponent<EventTrigger>()
}
return trigger
}
创建以一个控制虚拟摇杆StickJoyUI脚本,注册委托事件
TriggerEvent.Get(bgObj).onBeginDrag = OnDragBegin
TriggerEvent.Get(bgObj).onDrag = OnDrag
TriggerEvent.Get(bgObj).onEndDrag = OnDragEnd
TriggerEvent.Get(transform.Find("changeAttack").gameObject).onClick = OnChangeAttack
TriggerEvent.Get(transform.Find("AttackBtn").gameObject).onClick = OnAttackBtn
再来看看虚拟摇杆部分OnDragBegin OnDrag OnDragEnd 这个三个方法控制虚拟摇杆,
private void OnDragBegin(GameObject obj, PointerEventData evetData)
{
}
private void OnDrag(GameObject obj, PointerEventData evetData)
{ Vector2 point
//ScreenPointToLocalPointInRectangle("需要转换的对象的父级的RectTrasform","鼠标的位置","当前的摄像机","转换后的ui的相对坐标")
bg为要拖拽的对象的父级对象,里面还有一个小圆PointTf,鼠标的位置取拖拽事件的的position,鼠标的位置取拖拽事件的的摄像机,转
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(bgTf, evetData.position, evetData.pressEventCamera, out point)) {
//拖动的方向
Vector2 v = (point - Vector2.zero).normalized
x = v.x
y = v.y
if (Vector2.Distance(point, Vector2.zero) <= R)
{
pointTf.anchoredPosition = point
}
else //超出移动的半径
{
//位置 = 初始位置 + 方向 * 距离
pointTf.anchoredPosition = Vector2.zero + v * R
}
}
}
private void OnDragEnd(GameObject obj, PointerEventData evetData)
{
pointTf.anchoredPosition = Vector2.zero
x = 0
y = 0
}
Ps:2D角色还需要注意人物朝向问题
只需要把里面的的X值和Y值赋予给他实时更新,然后在写一个Flip方法判断朝向问题,本质是修改一下缩放的X改成相反的值就好了
//朝向
void Flip()
{
if (x >0)
{
transform.localScale = new Vector3(1, 1, 1)
}
else if (x <0)
{
transform.localScale = new Vector3(-1, 1, 1)
}
}
3D模式:把把X值和Y赋予个移动函数的x值和z值即可
接下用JS实现虚拟摇杆(思路跟上面差不多,但是数据的处理稍有差别而已)
首先引入玩家模块
var Player = require("player")
属性定义
cc.Class({
extends: cc.Component,
properties: {
stickNode:{
default:null,
type:cc.Node
},
fillNode:{
default:null,
type:cc.Node
},
skillBtn:{
default:null,
type:cc.Node
},
player:{
default:null,
type:Player
},
R:50,
stick_x:0,
stick_y:0
},
在初始化函数Onlade中注册事件
onLoad () {
this.stickNode = cc.find("Stick",this.node)
this.fillNode = cc.find("Stick/fill",this.node)
this.skillBtn = cc.find("skillBtn",this.node)
//注册开始拖拽,拖拽事件,拖拽结束事件,和点击事件,这个更上面的四个接口类似
this.stickNode.on(cc.Node.EventType.TOUCH_START,this.onTouchStart,this)
this.stickNode.on(cc.Node.EventType.TOUCH_MOVE,this.onTouchMove,this)
this.stickNode.on(cc.Node.EventType.TOUCH_END,this.onTouchEnd,this)
this.stickNode.on(cc.Node.EventType.TOUCH_CANCEL,this.onTouchCancel,this)
this.skillBtn.on("click",this.onClickSkillBtn,this)
},
onTouchStart(event)
{
},
onTouchMove(event)
{
var pos = event.getLocation()//v2类型 坐标系
//当前这个鼠标的世界坐标转换成当前节点的相对坐标
pos = this.stickNode.convertToNodeSpaceAR(pos)
if(pos.magSqr()<=this.R*this.R)
{
this.fillNode.setPosition(pos)
}
else
{
this.fillNode.x = pos.normalizeSelf().x*this.R
this.fillNode.y = pos.normalizeSelf().y*this.R
}
this.stick_x = pos.normalizeSelf().x
this.stick_y = pos.normalizeSelf().y
},
onTouchEnd(event)
{
this.fillNode.x = 0
this.fillNode.y = 0
this.stick_x = 0
this.stick_y = 0
},
onTouchCancel(event)
{
this.fillNode.x = 0
this.fillNode.y = 0
this.stick_x = 0
this.stick_y = 0
},
onClickSkillBtn()
{
//执行玩家脚本使用技能的方法
this.player.playSkill()
}
PS:计算上面的pos的方向, 上面为啥半径平方而不是把开方呢??,开方消耗性能,给半径平方两者比较也能比较,相对与前者开方,后者半径平方更加节省性能,采用迂回思路,感觉这种思想有很多地方都用到,就比如前面的浮点数处理,既然有误差,那么我可以放大倍数,然后要使用时候,我再缩小倍数。
新建一个unity3d项目“EasyTouch_test”。
通过“Assets”--“Import Package”--“Custom Package”导入easytouch.unitypackage,我这里用的3.1的版本,d出的窗口直接“Import”,出现兼容问题直接“I Make a Backup. Go Ahead”。
在场景中新建一个“Cube”,加上“Rigidbody”。
通过菜单中的”Tools“--”Hedgehog Team“--”EasyTouch“--”Extensions“--”Adding a new joystick“。
选择创建的”xxxxJoystick“,
把其中的 ”Joystick name“ 重新命名为 ”MoveJoystick“,
把下面的”Interaction type“设置为”Direct And Event“。
新建一个”Script“文件夹并新建一个”Easymove“的C#脚本,在其中添加如下的代码:
using UnityEngine
using System.Collections
public class Easymove : MonoBehaviour {
// Subscribe to events
void OnEnable(){
EasyTouch.On_TouchStart += On_TouchStart
EasyJoystick.On_JoystickMove += OnJoystickMove
EasyJoystick.On_JoystickMoveEnd += OnJoystickMoveEnd
}
// Unsubscribe
void OnDisable(){
EasyTouch.On_TouchStart -= On_TouchStart
}
// Unsubscribe
void OnDestroy(){
EasyTouch.On_TouchStart -= On_TouchStart
}
// Touch start event
public void On_TouchStart(Gesture gesture){
Debug.Log( "Touch in " + gesture.position)
}
//摇杆结束
void OnJoystickMoveEnd(MovingJoystick move)
{
if (move.joystickName == "MoveJoystick")
{
}
}
//移动摇杆中
void OnJoystickMove(MovingJoystick move)
{
if (move.joystickName != "MoveJoystick")
{
return
}
//摇杆偏移坐标
float joyPositionX = move.joystickAxis.x
float joyPositionY = move.joystickAxis.y
if (joyPositionY != 0 || joyPositionX != 0)
{
//设置人物朝向
transform.LookAt(new Vector3(transform.position.x + joyPositionX, transform.position.y, transform.position.z + joyPositionY))
//移动
transform.Translate(Vector3.forward * Time.deltaTime * 10)
}
}
}
编辑完成后把”Easymove“脚本拖拽添加到”Cube“中,然后运行就完成了,很简单吧。
虚拟摇杆由3部分组成
虚拟摇杆GameObject的层级
触屏控制
VirtualJoystick.cs
监听触屏、滑屏相关事件,发出自己的事件
VirtualJoystickAppearance.cs
虚拟摇杆的显示(包括设置其位置等)。
InputMgr.cs
监听虚拟摇杆的事件(SetDirEvent、StopSetDirEvent),控制Player移动。
Player.cs
外界(InputMgr)调用其Move方法控制其移动。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)