需求:
需要实现拖拽摇杆选择技能释放位置,释放技能。
原理:首先拆分需求,分为两部分,UI部分和场景部分,UI部分需要实现长按效果,长按后又要有拖动效果,将官方文档的示例代码改了改就实现了UI部分,如下图,实现的了长按显示摇杆按钮,并可以拖动:
然后就是场景部分,有时候是拖动圆的位置,有时候是旋转扇形矩形等指示器的方向,前一种就是以人物自身为圆心,用技能的范围长度为半径,配合着UI部分给出的弧度转换为方向坐标,再加上人物位置就是释放技能的位置,同时还要注意UI摇杆按钮有个拖拽的范围,这样转换到场景中就是指示器距离玩家的位置,如下图:
后一种就旋转指示器,这一种就是通过获取UI技能的摇杆按钮旋转的角度来旋转指示器的角度,如下图:
,上代码!
_proto.Init = function(){
this.skill2.on(Laya.Event.MOUSE_DOWN,this,this.onPreSkill2);
Laya.stage.on(Laya.Event.MOUSE_UP,this,this.onRelaseSkill2);
this.knob.visible = false;
this.curTouchId = 0;
/***手指(鼠标)是否按下****/
this.isDown = false;
/***摇杆的角度****/
this.angle = -1;
/***摇杆的弧度****/
this.radians = -1;
/***是否左手遥控****/
this.isleftControl = true;
//控制器中心点位置初始化
this.originPiont = new Laya.Point(this.skill2.x,this.skill2.y);
this.scale = 1;
}
_proto.onPreSkill2 = function(e){
Laya.timer.once(500,this,this.onHold,[e]);
}
_proto.onHold = function(e){
this.isHold = true;
this.knob.visible = true;
this.curTouchId = e.touchId;
//已按下
this.isDown = true;
//初始化摇杆控制点位置
this.knob.pos(this.skill2.x,this.skill2.y);
//摇杆移动控制事件监听
Laya.stage.on(Laya.Event.MOUSE_MOVE,this,this.onMove);
}
_proto.onRelaseSkill2 = function(e){
// 鼠标放开时,如果正在hold,则播放放开的效果
if (this.isHold)
{
this.isHold = false;
this.knob.visible = false;
Laya.stage.off(Laya.Event.MOUSE_MOVE,this,this.onMove);
//修改摇杆角度与弧度为-1(代表无角度)
this.radians = this.angle = -1;
}
Laya.timer.clear(this, this.onHold);
}
_proto.onMove = function(e){
//如果不是上次的点击id,返回(避免多点抬起,以第一次按下id为准)
if(e.touchId != this.curTouchId)return;
//将移动时的鼠标屏幕坐标转化为摇杆局部坐标
var locationPos = this.globalToLocal(new Laya.Point(Laya.stage.mouseX,Laya.stage.mouseY),false);
//更新摇杆控制点位置
this.knob.pos(locationPos.x,locationPos.y);
//更新控制点与摇杆中心点位置距离
this.deltaX = locationPos.x - this.originPiont.x;
this.deltaY = locationPos.y - this.originPiont.y;
//console.log(this.deltaX,this.deltaY);
//计算控制点在摇杆中的角度
var dx = this.deltaX * this.deltaX;
var dy = this.deltaY * this.deltaY;
//console.log(dx,dy);
this.angle = Math.atan2(this.deltaX,this.deltaY) * 180 / Math.PI;
if(this.angle < 0) this.angle += 360;
//对角度取整
this.angle = Math.round(this.angle);
//计算控制点在摇杆中的弧度
this.radians = Math.PI / 180 * this.angle;
//强制控制点与中心距离不超过80像素
if(dx+dy >= 80*80){
//控制点在半径为80像素的位置(根据弧度变化)
var x = Math.floor(Math.sin(this.radians) * 80 +this.originPiont.x);
var y = Math.floor(Math.cos(this.radians) * 80 + this.originPiont.y);
this.knob.pos(x,y);
this.scale = 1;
}
else{
//不超过80像素取原坐标
this.knob.pos(locationPos.x,locationPos.y);
this.scale = (dx + dy)/(80*80);
}
}
//场景部分
if(this.mMainUI.angle != -1)
{
var scale = this.mMainUI.scale;
var speedX = Math.sin(this.mMainUI.radians) * 3 * scale;
var speedZ = Math.cos(this.mMainUI.radians) * 3 * scale;
var pos = new Vector3();
Vector3.add(this._owner.transform.position,new Vector3(speedX,0,speedZ),pos);
this.range.transform.position = pos;
}
else{
//range就是那个白色的圈
this.range.transform.position = this._owner.transform.position;
}
参考链接:3D角色脚本控制与碰撞检测__LAYABOX技术文档
鼠标交互--Hold (layabox.com)