2013-12-15 00:02:06 janeky 阅读数 47170

手机游戏,尤其是mmo类的有,都少不了虚拟游戏摇杆。今天我们来学习如何利用Unity3d自带的摇杆组件,实现利用摇杆来控制角色的移动。

今天所用到的例子参考了网上的一个教程(http://www.unitymanual.com/thread-5189-1-1.html),原文用javascript实现了。我这里用c#来实现

                        (本文可以随意分享,请注明出处http://blog.csdn.net/janeky/article/details/17326711,谢谢!)

  • 具体步骤
1.导入Character Controller组件,主要是用到其中的角色模型
2.导入Standard Assets(Mobile)组件,里面包含了Joystick组件
3.创建一个Gui Texture,命名为Joystick。设置它的材料Texture 为 Joystick Thumb
  设置它的Pixel Inset .x,y Width,Hight
4.为Joystick添加脚本Joystick.cs
5.创建一个地形。不会的同学,可以直接引用到源码中的
6.将角色控制器中的Bip001加到Player上,初始化状态为idle
7.为Main Camera 添加 Smooth Follow脚本(角色控制器脚本中包含),使得摄像机可以跟随人物移动
8.为Main Camera添加自定义脚本 PlayerController.cs脚本
using UnityEngine;
using System.Collections;


public class PlayerController : MonoBehaviour
{
    //角色
    public GameObject player;
    //摇杆
    public Joystick joystick;


    void Update()
    {
        //摇杆没有被触发
        if (joystick.tapCount <= 0)
        {
            return;
        }
        //获取摇杆偏移
        var joyPositionX = joystick.position.x;
        var joyPositionY = joystick.position.y;


        if (joyPositionY != 0 || joyPositionX != 0)
        {
            //设置角色的朝向(朝向当前坐标+摇杆偏移量)
            player.transform.LookAt(new Vector3(player.transform.position.x + joyPositionX, player.transform.position.y, player.transform.position.z + joyPositionY));
            //移动玩家的位置(按朝向位置移动)
            player.transform.Translate(Vector3.forward * Time.deltaTime * 5);
            //播放奔跑动画
            player.animation.Play("run");
        }
        else
        {
            //播放待机动画
            player.animation.Play("idle");
        }
    }
}
  • 最终的效果图:


Joystick.cs
代码比较多,就不详细列出。

主要思路:记录触摸的位置,记录相关的偏移量。与此相关联的是GUI Texture组件。

  • 总结
官方自带的摇杆组件比较简单,可以基本实现简单的功能。但是,也存在很多的局限,比如更换外观比较繁琐,无法自适应屏幕的大小确定相对位置,基于GUI layer。为此,下节我们将介绍一个功能更加强大的摇杆组件Easy Touch 3,敬请期待!有任何问题欢迎一起探讨ken@iamcoding.com

  • 源码地址

http://pan.baidu.com/s/1GMnyQ

2016-09-06 11:25:11 qq_23337099 阅读数 1901
EasyTouch中提供了JoyStick(虚拟摇杆)的工具,该文主要讲述了unity中双摇杆的实现(左侧摇杆控制移动方向,右侧摇杆控制视角转向).(Unity版本5.3.4f1)
首先下载EasyToch插件,然后打开Project
如图,将插件导入至Project中,此时hierarchy面板中添加了Singleton of VirtualScreen,EasyTouch,Newjoystick三个Object,此时Singleton of VirtualScreen,EasyTouch不做改变,我们重点需要改变的是NewJoystick。
点击NewJoystick,在Inspector中,首先为joystick取个名字(JoyStick properties中Joystickname),改完之后在hierarchy中的Newjoystick也变成了你改的名字,在这我改成了move
接着就到重要的环节了——利用这个摇杆控制物体移动。
在遥感中控制物体移动有两种方法:在摇杆的Inspector面板中,有个属性是Joustick axes properties&events,在这个属性里面,第一个参数就是interaction type,翻译过来是作用类型,默认为direct,直接作用,在勾选Enable X axis,Enable Y axis,此时只要把你要操纵的物体拖入下面的Joystick X/Y to就可以直接对物体进行操纵了,那么是怎样操纵的呢,在Influenced中可以进行选择,它有4个类型:Rotate(旋转),Rotate Local(局部旋转),Translate(平移),Translate Local(局部平移),如果勾选旋转或局部旋转,此时操纵摇杆时会使物体旋转,如果勾选平移或局部平移,此时操纵摇杆时会使物体移动,当然前提是你别忘记在speed设置速度,如果速度为0那么怎么操纵摇杆物体都不会有变化。如图,此时我已经可以操纵人物移动了。但是这个操纵方式的弊端很快显现出来,那就是当物体的视角改变时,摇杆控制的方向并不会改变,这就对操纵造成了很大的麻烦,移动的方向总是固定的,对游戏造成了极差的体验,那么怎么解决这个问题?
很简单,将interaction type改为event Natification(事件通知),此时操纵摇杆并不是直接对物体进行修改了,而是相应摇杆提供的事件方法EasyJoystick.On_JoystickMoveEasyJoystick.On_JoystickMoveEnd,此时只需要在被控制的物体中添加一个脚本就行了
代码如下:
//OnEable函数,对象可用时回调
    void OnEnable()
    {
        //设置EasyJoystick.On_JoystickMove与EasyJoystick.On_JoystickMoveEnd
        EasyJoystick.On_JoystickMove += OnJoystickMove;
        EasyJoystick.On_JoystickMoveEnd += OnJoystickMoveEnd;
    }

    //销毁当前物体时同时销毁当前摇杆对物体的绑定
    void OnDisable()
    {
        EasyJoystick.On_JoystickMove -= OnJoystickMove;
        EasyJoystick.On_JoystickMoveEnd -= OnJoystickMoveEnd;
    }

    //移动摇杆结束 
    void OnJoystickMoveEnd(MovingJoystick move)
    {
        //停止时
        if (move.joystickName.Equals("move"))
        {
        }
    }

    //移动摇杆中
    void OnJoystickMove(MovingJoystick move)
    {
        if (move.joystickName.Equals("move"))
        {
            return;
        }
        //获取摇杆中心偏移的坐标 
        float joyPositionX = move.joystickAxis.x;
        float joyPositionY = move.joystickAxis.y;
        //设置角色朝摇杆方向移动
        if (joyPositionX != 0 || joyPositionY != 0)
        {
            this.transform.Translate((new Vector3(joyPositionX,0, joyPositionY))* Time.deltaTime * speed);
        }
    }


此时摇杆就可以控制物体朝摇杆移动方向移动了。
接下来控制物体视野:
再导入一个new joystic,更名为view,首先为物体设置第一人称视角(将camera绑定到物体身上),然后设置
作用类型为Direct,如图
此时直接摇杆控制物体旋转就好了,由于camera与物体是绑定在一起的,所以旋转物体时camera也会跟着旋转,达到一种视野变化效果。
然后就OK了,这样很好的实现了双摇杆实现控制物体视角与运动
2018-12-19 14:39:19 qq_37352817 阅读数 795

很多手游里面都有一个滑轮控制人物移动

我前段时间也研究了一下

下面附上源码,因为有注释我就不多说什么了

源码:



public class CoronaScripts : MonoBehaviour {

    大圆

    private RectTransform bigRect;

    小圆

    private RectTransform smallRect;

    滑轮被激活;默认没有

    private bool isActiveTrue = false;

    屏幕分辨率比率;这里Canvas是根据宽来缩放的

    private float biLv;

    用来存储鼠标和大圆的距离;是一个由大圆坐标指向鼠标坐标的方向向量

    private Vector3 dis;



    void Start () {

        bigRect = this.transform.GetChild (0).GetComponent<RectTransform> ();

        smallRect = bigRect.transform.GetChild (0).GetComponent<RectTransform> ();

        屏幕分辨率的宽除以实际屏幕宽度

        biLv = 1280f/ Screen.width;

    }



    void Update () {

        if (Input.GetMouseButtonDown (0)) {

            轮盘在屏幕左下角占屏幕1/4的大小范围有效

            if (Input.mousePosition.y < Screen.height / 2 && Input.mousePosition.x < Screen.width / 2) {

                限制左边和下边的间距,是上面的1/15的长度

                if (Input.mousePosition.y > Screen.height / 15 && Input.mousePosition.x > Screen.width / 15) {

                    滑轮当前状态被激活

                    isActiveTrue = true;    

                    显示滑轮

                    bigRect.gameObject.SetActive (true);

                    生成滑轮大圆的位置在鼠标在实际屏幕的位置

                    bigRect.anchoredPosition = Input.mousePosition * biLv;

                }

            }

        }

        被激活要做的事情;控制小圆的移动

        if (isActiveTrue) {

            小圆的坐标:等于相对于父物体大圆鼠标的坐标;等于大圆指向鼠标的一个向量;等于鼠标坐标减去大圆坐标;

            smallRect.anchoredPosition = Input.mousePosition * biLv - bigRect.anchoredPosition3D;

            鼠标到大圆的距离;是一个方向指向鼠标的向量

            dis = smallRect.anchoredPosition;

            如果鼠标到大圆的距离大于100

            if (dis.magnitude > 100) {

                将这个向量转换成单位向量乘以一百就是小圆的位置了

                dis = smallRect.anchoredPosition.normalized * 100;

                smallRect.anchoredPosition = dis;

            }

        }

        if (Input.GetMouseButtonUp (0)) {

            isActiveTrue = false;

            滑轮隐藏

            bigRect.gameObject.SetActive (false);

            小圆位置归位

            smallRect.anchoredPosition = Vector2.zero;

        }

    }

}


2016-11-22 17:04:42 huyijian1314 阅读数 829

摇杆和虚拟摇杆在手游中的应用非常多,在Unity中的实现方法或许有很多,以下是我在做项目的时候写的一个摇杆的控制器。我采用的是NGUI做的摇杆,UI界面用NGUI和UGUI因人而异。有好的方案也望在评论中回复~~0v0
using UnityEngine;
using System.Collections;

public class JoyStick : MonoBehaviour
{
private bool IsPress = false;
private Transform Button;
public static float h = 0;
public static float v = 0;

void Awake()
{
    Button = transform.Find("button");
}
void OnPress(bool IsPress)
{
    this.IsPress = IsPress;
    if (IsPress == false)
    {
        Button.localPosition =Vector3.zero;//局部坐标中心位置
        h = 0;
        v = 0;
    }
}
void Update()
{
    if (IsPress)
    {
        Vector2 TouchPosition = UICamera.lastTouchPosition;//获取拖拽的位置
        TouchPosition -= new Vector2(91, 91);
        float Distance = Vector2.Distance(Vector2.zero, TouchPosition);//获取与原点的距离
        if (Distance > 70)//先在控制面板得到摇杆局部坐标的最大距离
        {
            TouchPosition = TouchPosition.normalized * 70;//获取单位向量后进行操作
            Button.localPosition = TouchPosition;//超过最大距离则限定在边缘
        }
        else
        {
            Button.localPosition = TouchPosition;//没有超出接线则为目前的拖拽点
        }
        h = TouchPosition.x / 70;//单位向量
        v = TouchPosition.y / 70;
    }
}

}

2017-11-30 23:15:08 niujin561 阅读数 2176

image

最近想着自己动手做款游戏,算是工作之余练练手,游戏规模不需要多大,毕竟个人时间有限,能简单实现我想要的功能就好。就游戏的类型方向的选择,我之前考虑做手游MOBA方向,当然也尝试做了下,发现水有点深,况且自身能力还不足以支撑整个游戏的开发,所以退而求其次转战做款联机小游戏,怎么说之前也研究过网络通信这块。当前今天的主角不是联机小游戏,而是我在探索手游MOBA的时候,针对目前手游摇杆插件来定制自己的摇杆。

摇杆的构成与原理

目前通过Unity构造的手游,大多数的UI应该都是基于UGUI做的,本文的摇杆也是如此,准确来说其实也就是两个图片构成,具体构成图如下
摇杆.png
摇杆能够控制角色移动的原理说来也不难,主要在于摇杆转动方向转化到角色前进的方向,UI控制的方向是二维的,角色移动需要的是三维的方向,有人觉得不晓得怎么转化,其实3D物体移动的时候垂直方向上是不太需要变化的,也就是说只需要我们将摇杆传递的二维偏移量转化成角色移动方向向量的其他两个值就可以了。

可能我说的不是很精简或者通俗,甚至于有错误也请多多包涵,批评指正,如下是效果图
Demo.gif

代码解析

说了那么多,我还是以代码为例来具体说明摇杆是如何实现角色移动的

SticktController.cs

using UnityEngine;
using System;

public class SticktController : MonoBehaviour {

private RectTransform sticktTransform;
private RectTransform sticktBgTransform;
//private GameObject touchRotatePanel;
private Vector3 firstSticktPos;
private Vector2 firstSticktPos2;
private bool isUp = false;
private bool isDown = false;
private float backSpeed = 4f;
private float radius;
private float offsetX;
private float offsetY;
private float rotateX;
private float rotateY;
private Vector3 downMousePos;

public Action<float,float> OnMoveStickt;
public Action<float,float> OnTouchRotate;
public Action OnJumpClick;
public Action OnShootClick;

void Start () {
    //touchRotatePanel = transform.Find ("TouchRotate").gameObject;
    sticktTransform = transform.Find ("SticktBg/Stickt").GetComponent<RectTransform> ();
    sticktBgTransform = transform.Find ("SticktBg").GetComponent<RectTransform> ();
    firstSticktPos = sticktTransform.position;
    firstSticktPos2 = sticktTransform.anchoredPosition;
    radius =  sticktBgTransform.sizeDelta.x / 2;

}

void Update () {

    if (isUp) {
        sticktTransform.position = Vector3.Lerp (sticktTransform.position,firstSticktPos,Time.deltaTime * backSpeed);
    }

    if (isDown) {
        if (OnMoveStickt != null) {
            OnMoveStickt (offsetX, offsetY);
        }
    }
}

public void OnSticktDrag(){

    float distance = Vector3.Distance (sticktBgTransform.position, Input.mousePosition);
    if (distance < radius) {
        sticktTransform.position = Input.mousePosition;

    } else {
        Vector3 targetDirection = Input.mousePosition - firstSticktPos;
        sticktTransform.position = firstSticktPos +  targetDirection.normalized * radius;

    }

    offsetX = sticktTransform.position.x - firstSticktPos.x;
    offsetY = sticktTransform.position.y - firstSticktPos.y;
}

public void OnPointerUp(){
    isUp = true;
    isDown = false;
}

public void OnPointerDown(){
    isUp = false;
    isDown = true;
}

//public void OnTouchDragRotate(){


//  rotateX = Input.mousePosition.x - downMousePos.x;
//  rotateY = Input.mousePosition.y - downMousePos.y;

//  if (OnTouchRotate != null) {
//      OnTouchRotate (rotateX, rotateY);
//  }
//}

public void OnTouchDragDown(){
    downMousePos = Input.mousePosition;
}

}

这段代码就是控制摇杆UI的,大体的功能实现大家可以从代码中找到答案,我说下大概的思路:鼠标点击摇杆的时候让摇杆跟随鼠标移动,但是有范围限制,受限于底座的圆形区域,一旦鼠标控制的摇杆到达限制区域的极限就让摇杆不再跟随鼠标,当然鼠标移动的方向即使是在极限区域的摇杆也是需要跟随的,鼠标抬起的时候摇杆会回弹到初始位置;至于如何控制角色行走主要在于代码中设定的委托OnMoveStickt ,传递出去的就是摇杆在屏幕的偏移量,需要将其绑定到角色移动脚本上就好了。

代码工程看这里

目前提供的代码只是针对摇杆UI的控制,至于要达到效果图中的样子还需要角色移动的脚本,我在这就不贴代码了,有兴趣的话可以看这里

后续

说到自己想做个联机小游戏,其实目前已经在做了,不过完成度不是很好,只能说基本完成功能,后面呢打算继续优化,当然也会分享出来具体的实现方案,今天就到这里~

没有更多推荐了,返回首页