Unity随记

//切换场景时怎么能让音乐不停?

///////////////////////////////////////////////////////////////////

//切换场景时怎么防止某个物体销毁?

//代码

void Awake() { DontDestroyOnLoad(transform.gameObject); }

//这个游戏对象不要是子物体

//C# 中的 float为小数要带 f 符号如

//代码

float movev = 0.3f;

//

///////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////

//关于2d游戏Z轴自转解决方案

//或使用代码

//在每次旋转后,修正Z值

//修正Z轴的倾斜,使观察始终是正向的

Vector3 eulerAngle = transform.rotation.eulerAngles ;

eulerAngle.z = 0 ;

transform.rotation = Quaternion.Euler( eulerAngle ) ;

/////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////

//unity,ugui如何实现button长按,就是如何监听按下和抬起,求一个完整的小例子谢谢。

using UnityEngine;

using System.Collections;

public class ButtonsScript : MonoBehaviour {private int repeatTime = 0;private string info = "";void Start () {}// Update is called once per framevoid Update () {}void OnGUI(){// 文本显示GUI.Label (new Rect (50, 200, 200, 50), info);// 第一个文字按钮GUI.color = Color.yellow; //按钮文字颜色 GUI.backgroundColor = Color.red; //按钮背景颜色if(GUI.Button(new Rect(50,250,200,30), "Button1")) {info = "按下了Button1";}// 持续按下的按钮if(GUI.RepeatButton(new Rect(50,400,200,30),"按钮按下中")){info = "按钮按下中的时间:"+ repeatTime;repeatTime++; } }}

////////////////////////////////////////////////////////////////////////////////////////////

///////////

c#作为一门强大的编程语言绝对有计时器这样的功能,而且有3钟,unity能用的有2种。System.Timers.Timer t = new System.Timers.Timer(1000);//实例化Timer类,设置间隔时间,单位为毫秒; t.Elapsed += new System.Timers.ElapsedEventHandler(event);//到达时间的时候执行“event”函数(方法); t.AutoReset = true;//设置是执行一次(false)还是一直执行(true),一直执行就是每到设定的时间都执行一次。; t.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件(这个一定要是true,否则无法执行);public void event(object source, System.Timers.ElapsedEventArgs e) //被绑定的方法(函数){ 在这儿添加你想执行的内容} 另外一种我就不介绍了。我测试了一下,除了不能在Flash平台使用这个计时器,其他平台都行。计时器还有很多强大功能,你自己慢慢研究吧!

///////////

///////////////////////

unity3d Update()和FixedUpdate()的区别

从字面上理解,它们都是在更新时会被调用,并且会循环的调用。

但是Update会在每次渲染新的一帧时,被调用。

而FixedUpdate会在每个固定的时间间隔被调用,那么要是Update 和FixedUpdate的时间间隔一样,是不是就一样呢?答案是不一定,因为Update受当前渲染的物体,更确切的说是三角形的数量影响,有时快有时慢,帧率会变化,update被调用的时间间隔就发生变化。

但是FixedUpdate则不受帧率的变化,它是以固定的时间间隔来被调用,那么这个时间间隔怎么设置呢?

Edit->Project Setting->time下面的Fixed timestep。

///////////////////////

//////////////////////////////////////////////////

Time

.time 时间

static var time : float

Description描述

The time this frame has started (Read Only). This is the time in seconds since the start of the game.

此帧开始的时间(只读)。这是以秒计算到游戏开始的时间。也就是说,从游戏开始到到现在所用的时间。

When called from inside MonoBehaviour's FixedUpdate

, returns fixedTime property.

当在MonoBehaviour

的FixedUpdate里调用的时候,返回的是fixedTime属性。

  • C#
  • JavaScript
// Instantiates a projectile off every 0.5 seconds,
// if the Fire1 button (default is ctrl) is pressed.
//如果Fire1按钮被按下(默认为ctrl),每0.5秒实例化一发子弹

var projectile : GameObject; var fireRate = 0.5; private var nextFire = 0.0; function Update () { if (Input.GetButton ("Fire1") && Time.time > nextFire) { nextFire = Time.time + fireRate; var clone = Instantiate (projectile, transform.position, transform.rotation); } }

//////////////////////////////////////////////////

/////////////////////////

各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是http://qinyuanpei.com。

最近因为项目需要决定尝试自己来实现一个虚拟摇杆,所以在今天的文章中我们的目标是使用uGUI来制作一个可以在移动平台稳定运行的虚拟摇杆(请不要问我为什么不使用NGUI来实现,你说我做个虚拟摇杆有必要在项目里导入那么多的资源嘛23333)。关于使用第三方插件来实现虚拟摇杆,请大家参照我以前写的文章

unity

3D游戏开发之使用EasyTouch虚拟摇杆控制人物移动,在这里就不再赘述了。

虚拟摇杆这种输入方式相信大家在

手机游戏

平台上已经相当的熟悉了,首先我们来简单了解下虚拟摇杆的设计原理。虚拟摇杆有一张固定的

2D

贴图(背景层)和一张可拖动的2D贴图(控制层)构成,默认情况下控制层在背景层的中心,我们称这个位置为初始位置,当移动控制层后移动层的位置会发生变化,此时控制层的当前位置和初始位置两点间可以计算出一个2D向量,通过这个向量我们就可以判断虚拟摇杆的移动方向。在经典的八方向摇杆导航中摇杆中可移动方向被分成了上、左上、右上、下、左下、右下、左、右共8个方向。我们知道根据三角函数可以非常容易地计算出这个2D向量的角度并由此判定摇杆是在向着这8个方向中的哪一个方向移动。在今天的文章中,我们不需要考虑这8个方向,因为我们可以向任何一个方向进行移动。

好了,首先在场景中创建两个Image组件和一个空的游戏体,然后将这两个Image组件拖拽到这个空的游戏体下使它们称为其子节点。这里需要注意的是这两个Image的层级关系。现在我们来编写脚本,这个脚本将被添加到控制层物体上:

using

UnityEngine;

using

System.Collections;

using

UnityEngine.UI;

using

UnityEngine.EventSystems;

public

class JoyStick : MonoBehaviour,IPointerDownHandler, IPointerUpHandler, IDragHandler

{

    

///

    

/// 摇杆最大半径

    

/// 以像素为单位

    

///

    

public

float JoyStickRadius = 50;

    

///

    

/// 摇杆重置所诉

    

///

    

public

float JoyStickResetSpeed = 5.0f;

    

///

    

/// 当前物体的Transform组件

    

///

    

private

RectTransform selfTransform;

    

///

    

/// 是否触摸了虚拟摇杆

    

///

    

private

bool isTouched = false;

    

///

    

/// 虚拟摇杆的默认位置

    

///

    

private

Vector2 originPosition;

    

///

    

/// 虚拟摇杆的移动方向

    

///

    

private

Vector2 touchedAxis;

    

public

Vector2 TouchedAxis

    

{

        

get

        

{

            

if

(touchedAxis.magnitude < JoyStickRadius)

                

return

touchedAxis.normalized / JoyStickRadius;

            

return

touchedAxis.normalized;

        

}

    

}

    

///

    

/// 定义触摸开始事件委托

    

///

    

public

delegate void JoyStickTouchBegin(Vector2 vec);

    

///

    

/// 定义触摸过程事件委托

    

///

    

/// 虚拟摇杆的移动方向

    

public

delegate void JoyStickTouchMove(Vector2 vec);

    

///

    

/// 定义触摸结束事件委托

    

///

    

public

delegate void JoyStickTouchEnd();

    

///

    

/// 注册触摸开始事件

    

///

    

public

event JoyStickTouchBegin OnJoyStickTouchBegin;

    

///

    

/// 注册触摸过程事件

    

///

    

public

event JoyStickTouchMove OnJoyStickTouchMove;

    

///

    

/// 注册触摸结束事件

    

///

    

public

event JoyStickTouchEnd OnJoyStickTouchEnd;

    

void

Start ()

    

{

        

//初始化虚拟摇杆的默认方向

        

selfTransform =

this

.GetComponent();

        

originPosition = selfTransform.anchoredPosition;

    

}

    

public

void OnPointerDown(PointerEventData eventData)

    

{

        

isTouched =

true

;

        

touchedAxis = GetJoyStickAxis(eventData);

        

if

(

this

.OnJoyStickTouchBegin !=

null

)

            

this

.OnJoyStickTouchBegin(TouchedAxis);

    

}

    

public

void OnPointerUp(PointerEventData eventData)

    

{

        

isTouched =

false

;

        

selfTransform.anchoredPosition = originPosition;

        

touchedAxis = Vector2.zero;

        

if

(

this

.OnJoyStickTouchEnd !=

null

)

            

this

.OnJoyStickTouchEnd();

    

}

    

public

void OnDrag(PointerEventData eventData)

    

{

        

touchedAxis = GetJoyStickAxis(eventData);

        

if

(

this

.OnJoyStickTouchMove !=

null

)

            

this

.OnJoyStickTouchMove(TouchedAxis);

    

}

    

void

Update()

    

{

        

//当虚拟摇杆移动到最大半径时摇杆无法拖动

        

//为了确保被控制物体可以继续移动

        

//在这里手动触发OnJoyStickTouchMove事件

        

if

(isTouched && touchedAxis.magnitude>=JoyStickRadius)

        

{

            

if

(

this

.OnJoyStickTouchMove !=

null

)

                

this

.OnJoyStickTouchMove(TouchedAxis);

        

}

        

//松开虚拟摇杆后让虚拟摇杆回到默认位置

        

if

(selfTransform.anchoredPosition.magnitude > originPosition.magnitude)

            

selfTransform.anchoredPosition -= TouchedAxis * Time.deltaTime * JoyStickResetSpeed;

    

}

    

///

    

/// 返回虚拟摇杆的偏移量

    

///

    

/// The joy stick axis.

    

/// Event data.

    

private

Vector2 GetJoyStickAxis(PointerEventData eventData)

    

{

        

//获取手指位置的世界坐标

        

Vector3 worldPosition;

        

if

(RectTransformUtility.ScreenPointToWorldPointInRectangle (selfTransform,

                 

eventData.position, eventData.pressEventCamera,

out

worldPosition))

            

selfTransform.position = worldPosition;

        

//获取摇杆的偏移量

        

Vector2 touchAxis = selfTransform.anchoredPosition-originPosition;

        

//摇杆偏移量限制

        

if

(touchAxis.magnitude >= JoyStickRadius)

        

{

            

touchAxis = touchAxis.normalized * JoyStickRadius;

            

selfTransform.anchoredPosition = touchAxis;

        

}

        

return

touchAxis;

    

}

}

在这段脚本中,我们实现了OnPointerDown、OnPointerUp和OnDrag三个uGUI事件接口,然后注册了相关的事件委托,这里借鉴了EasyTouch的设计,可以使得虚拟摇杆的逻辑和角色控制逻辑相互分离。这里的核心方法是GetJoyStickAxis()方法,通过这个方法我们可以获得一个Vector2类型的值,它表示的是未标准化过的虚拟摇杆的偏移量。这里的RectTransformUtility.ScreenPointToWorldPointInRectangle()方法表示将一个屏幕坐标转化为对应RectTransform的世界坐标,RectTransform的anchoredPosition属性表示的是当前元素在场景中的屏幕坐标。我们知道屏幕坐标是以像素为单位的,因此这里使用屏幕坐标可以计算出虚拟摇杆在水平方向和垂直方向上移动了多少个像素,我们以此来作为虚拟摇杆的偏移量衡量指标。TouchedAxis是经过标准化以后的偏移量,我们将把这个值传递到事件委托中以提供给外部来调用。好了,要说的就这些了,没有说到的大家可以看看代码里的注释或者是在博客中给我留言,就是这样啦。

接下来,我们在场景中添加一个角色模型来测试我们编写的虚拟摇杆,因为在JoyStick中我们已经定义了事件委托,所以在这里就是简单的调用啦。好了,我们一起来看看代码吧!

using

UnityEngine;

using

System.Collections;

public

class JoyStick3D : MonoBehaviour

{

    

private

JoyStick js;

    

void

Start ()

    

{

        

js = GameObject.FindObjectOfType ();

        

js.OnJoyStickTouchBegin += OnJoyStickBegin;

        

js.OnJoyStickTouchMove += OnJoyStickMove;

        

js.OnJoyStickTouchEnd += OnJoyStickEnd;

    

}

    

void

OnJoyStickBegin(Vector2 vec)

    

{

        

Debug.Log(

"开始触摸虚拟摇杆"

);

    

}

    

void

OnJoyStickMove (Vector2 vec)

    

{

        

Debug.Log(

"正在移动虚拟摇杆"

);

        

//设置角色朝向

        

Quaternion q = Quaternion.LookRotation (

new

Vector3 (vec.x, 0, vec.y));

        

transform.rotation = q;

        

//移动角色并播放奔跑动画

        

transform.Translate(Vector3.forward * 75f * Time.deltaTime);

        

animation.CrossFade(

"Run"

);

    

}

    

void

OnJoyStickEnd ()

    

{

        

Debug.Log(

"触摸移动摇杆结束"

);

        

//播放默认待机动画

        

animation.CrossFade(

"idle"

);

    

}

    

void

OnGUI()

    

{

        

GUI.Label(

new

Rect(30,30,200,30),"3D模式下的虚拟摇杆测试");

    

}

}

最终程序的运行效果如下图所示,我们编写的这个虚拟摇杆可以在手机上完美的运行,欢饮大家来一起测试和吐槽!

好了,今天的内容就是这样啦!欢迎大家继续关注我的博客,希望大家喜欢!

教你一步步实现一个虚拟摇杆

我来帮楼主补充下

如果你跟我一样没设角色动画,那么要注释掉这2行动画调用代码

//最后  解决掉问题的请谢我, 这是我补充的. 不是楼主补充的.不要弄错人啦啊

/////////////////////////​

////////////

我插个小问题,手机上input。getmousedown也可以用于判断玩家点击屏幕的吧 ​

​ 手机用 touch 操作吧

​http://game.ceeger.com/Manual/Input.html

////////////​

 
上一篇:Java面向对象课程设计——购物车


下一篇:【Mac + Android】之Android Studio 环境搭建,AVD模拟器运行(包括:命令行运行AVD,并且Genymotion模拟器插件配置运行)