您的位置:首页 > 移动开发 > Unity3D

Unity各种小技巧函数方法—RPG黑暗之光解析

2015-11-03 20:35 736 查看

修改游戏中的默认鼠标图标:

File->BuildSettings->PlayerSettings:中的Defult Cursor,
将你要使用的图标图片拖动到Defult Cursor中即可;

给场景添加天空盒子:

首先需要需要Main—Camera中的Clear Flags选为:Skybox,然后为MainCamera Add Component一个Skybox,修改其中的Custom Skybox材质;

实现镜头的缓慢拉近效果:
首先定义一个float 类型的值(沿着哪方向改变的就定义哪个方向上的终点值),用translate方法强行改变摄像机的坐标就可以了。
void Update()
{
if(transform.position.z<endZ)
{
transform.translate(Vector3.forword*speed*Time.deltaTime);
}

}

使用NGUI和白色图片给场景添加渐显效果:

首先在UIroot下创建一个Texture,为此Textrue添加Tween Alpha透明度动画,改变其From 和to 的值即可,如果运行后没有效果,可以修改Tweener中的StartDelate 的值,

处理任何按键按下的事件:
首先定义一个bool 类型的
isAnyKeyDown = falsel;
void Update()
{
if(isAnyKeyDown == false)
{
if(Input.anyKey)
{
// 添加事件;在事件中处理isAnyKeyDown = true;

}
}

}
Input.anyKey:任意键,bool类型。检测是否某一按键杯按住。

关于在脚本中查找物体:
1.通过检视面板指定参数:
可以吧参数显示在检视面板上面,然后拖拽游戏对象到检视面板中的target位置

2.使用tranform.Find 方法寻找所有的子物体。
按名字查找物体的话,this.transform.parent.Find("")其寻找的是同级的,寻找同级需要先找到同级的父物体,然后在父物体下查找同级。

3.指定名字或者标签。
通过名字:GameObject.Find("名字");
通过标签:GameObject。FInWithTag("Tag");

PlayerPrefs:玩家偏好,
在游戏会话中储存和访问玩家偏好设置。可以当做全局变量来使用。
Class Functions类函数:

SetInt :
static function SetInt (key :
string, value : int) : void
Sets the value of the preference identified by key.

设置由key确定的偏好值。

GetInt :
static function GetInt (key :
string, defaultValue : int = 0) : int
Returns the value corresponding to key in the preference file if it exists.

如果存在,返回偏好文件中key对应的值。

SetFloat:
static function SetFloat (key :
string, value : float) : void
Sets the value of the preference identified by key.

设置由key确定的偏好值。

GetFloat:

static function GetFloat (key : string, defaultValue :
float = 0.0F) : float

Returns the value corresponding to key in the preference file if it exists.

如果存在,返回偏好文件中key对应的值。如果不存在,将返回默认值;

SetString:
static function SetString (key :
string, value : string) : void
Sets the value of the preference identified by key.

设置由key确定的偏好值。

GetString:

static function GetString (key : string, defaultValue :
string = "") : string

Returns the value corresponding to key in the preference file if it exists.

如果存在,返回偏好文件中key对应的值。

HasKey:

static function HasKey (key : string) : bool

Returns true if key exists in the preferences.

如果key在偏好中存在,返回true。

DeleteKey:

static function DeleteKey (key : string) : void

Removes key and its corresponding value from the preferences.

从偏好中删除key和它对应的值。

DeleteAll:

static function DeleteAll () : void

Removes all keys and values from the preferences. Use with caution.

从偏好中删除所有key。请谨慎使用。

控制所有角色的显示和控制:
首先定义一个Prefabs 的数组,用来存储要实例化的游戏角色,然后定义一个数组用来存储实例化出来的角色对象。
在Start函数中赋值:
public GameObject[] characterPrefabs;
private GameObject[] characterGameObjects;
private int length;
void Start()
{
length = characterPrefabs.Length;
for(int i = 0;i<lengh;i++)
{
characterGameObjects[i] = GameObject.Instantiate(characterPrefabs[i],tranform.position,tranform.rotation) as GameObject;

}
}

储存游戏创建时的角色名称:用PlayerPrefs偏好设置。

Tag管理类:public const string ground= "Ground",用const来设置这是一个共有 的不可变的变量,不可修改。

实例化行走时的点击效果:
首先定义出我们实例化的Prefab;
添加以下代码:
public GameObject effect_click_prefab;

void Update()
{
if(Input.GetMouseButtonDown(0)) //获取鼠标左键的按下,
{
Ray ray = Camera.main.ScreenPointToRay(INput.mousePosition); //将鼠标的按下时的点转化为一条射线,
RaycastHit hitInfo; //射线的信息。
bool isCollider = Physics.Raycast(ray,out hitInfo); //标记是否检测到了碰撞,
if(isCollider && hitInfo.collider.tag == Tags.ground) //如果点击的是地面。
{
ShowClickEffect(hitINfo.point); //调用相应的函数,实例化Prefab;

}

}

}
void ShowClickEffect(Vector3 hitPoint)
{

GameObject.Instantiate(effect_click_prefab,hitPoint,Quaternion.identity); //实例化,Quaternion.identity:恒等式旋转,

返回恒等式旋转(只读)。这个四元数对于“无旋转”:这个物体完全对齐于世界或父轴。

}

将目标朝向点击鼠标的位置:
首先我们要获取到鼠标在屏幕上的点击位置,然后让主角的position和鼠标点击位置的position在Y轴上保持一致,只需要利用tranform.LookAt()函数改变主角的X,Z的即可;
简短的代码:
targetPosition = new Vector3(targetPosition.x,tranform.postion.y,targetPosition.z);
this.tranform.LookAt(targetPosition);

控制主角移动动画的播放:
首先要让主角这个gameobject上有Animation组件,然后将主角的所有动画都拖动到Animation组件的Animations属性上,为Animation组件的Animation参数添加默认的Idle动画。
然后我们可以在PlayerMove脚本中定义一个枚举类型的PlayerState:Moving,Idle;
我们可以创建一个PlayerAnimation的脚本来控制主角的动画播放、然后使用Aimation.CrossFade:淡入淡出,(此函数在一定时间内淡入淡出名称为name的动画,并且淡出其他动画)
Aimation.CrossFade:淡入淡出,

function CrossFade (animation : string, fadeLength :
float = 0.3F, mode : PlayMode = PlayMode.StopSameLayer) : void

此函数在一定时间内淡入淡出名称为name的动画,并且淡出其他动画。

如果模式是PlayMode.StopSameLayer,在同一层的动画将在动画淡入的时候淡出。如果模式是PlayMode.StopAll,所有动画将在淡入的时候淡出。
If the animation is not set to be looping it will be stopped and rewinded after playing.

如果动画没有被设置成循环,它将停止并且在播放完成之后倒带至开始。

控制相机对主角的跟随:
首先我们在Start方法中要让相机LookAt主角,并计算出刚开始时的偏移量,在Update中跟据刚开始时的偏移量,以后每一帧都让摄像机的位置 = Player加上这个偏移量;
void Start()
{
tranform.LookAt(Player.Position);
offestPosition = tranform.position - Player.position;
}
void Update()
{
tranform.position = offestPosition +Player.position;

}

使用鼠标滑动控制相机的拉近和拉远效果;
我们只需在Update中调用一个这个功能的函数就行了。
思路:在得到鼠标滑动的信息后,改变相机和主角的位置便偏移值就行了。
void ScrollView()
{
distance = offestPosition.magniyude; //首先计算相机和主角的距离值。
distance += Input.GetAxis("Mouse ScrollWheel")*scrollSpeed; 通过滑动的信息来改变此距离值,
offestPosition = offestPositipn.normalized *distance ; 在将此距离值化为主角和相机的偏移向量,这样相机的位置就会改变,视野也会改变。

}
上面这个拉近和拉远还是存在问题,我们必须要给拉近拉远效果一个判断,不要让它超过临界值,不然会出现Bug;

鼠标控制视野的左右和上下旋转:
我们在Carmera上添加一个脚本函数:
void RotateView()
{

if(INput.GetMouseButtonDown(1))

{

isRotating = true;

}

if(Input.GetMouseButtonUp(1))

{

isRotating = false;

}

if(isRotating)

{

trannsform.RotateAround(player.position,Vector3.up,rotateSpeed*Input.GetAxis("Mouse X")); //左右旋转,

Vector3 originalPos = tranfrom.position; //我们记录下左右旋转后的位置和角度

Quaternion originalRotastion = tranform.rotation;

tranform.RotateAround(player.position,tranform.right,-rotateSpeed*Input.GetAxis("Mouse Y")); //上下旋转, //影响的属性有两个,position,rotation。

float x= tranform.euerAngles.x;

if(x<10||x>80)

{

tranform.position.= originalPos;

tranform.rotation = originalRotation; //如果上下旋转(绕着X轴)到边界,我们将属性归位原来的,就是让旋转无效

}

}

offsetPosition = tranform.position - player.position;

}
:注意:我们在使用Unity自带的RotateAround:

function RotateAround (point : Vector3, axis :
Vector3, angle : float) : void
按照angle度通过在数世界坐标的point轴旋转物体。
简单的说,按照多少度在世界坐标的某位置旋转物体;
时需要让摄像机按照目标为旋转点,在旋转过后一定要记得更新摄像机和目标人物的差值。
如果我们在Update函数中使用拉近拉远函数和旋转视野函数,我们需要把RotateView函数放在前面。因为在RotateView函数中会改变offsetPosition的朝向,ScrollView会改变offsetPosition的值,如果先调用ScrollView后调用RotateView会造成offsetPostion被重置。

关于如何在点击UI控件时不让角色运动:
我们在点击UI控件如:button时会遇到主角移动的Bug,其实这个问题很好解决,我们只需加一个判断就ok了,:if(UICamera.hoveredObject== null):这个判断是当前位置下是否有UI控件。

在主场景中我们如何处理鼠标在collider上的事件:
OnMouseOver()函数是Unity自带的脚本函数,我们党鼠标位于这个collider上的时候没回在每一帧调用这个方法。
我们只需要在这个函数里面处理事件的相应和处理。

当鼠标位于NPC上的时候改变鼠标的图标:
public Textrue2D cursor_normal;
public Textrue2d cursor_talk;

private Vector2 hotspot = Vector2.zero;
private CursorMode mode = CursorMode.Auto;
public void SetNormal()
{
Cursor.SetCursor(cursor_normal,hotspot,mode);

}

public void SetNpcTalk()
{
Cursor.SetCursor(cursor_talk,hotspot,mode);

}
然后做成单例模式在OnMouseOver调用SetNpcTalk方法,在OnMouseExit调用SetNormal方法就ok了;hotspot是把那个位置的鼠标的点作为有效点击点,mode是模式。是软件修改还是系统修改图标。

功能按钮的点击事件监听:
添加Box Cillder,我们需要在UIButton脚本(Unity自带,只需要给物体添加上就行了)OnClick将处理放置处理点击事件的脚本的物体拖动进去,然后选择函数方法就行了,至于把处理相应事件的脚本放在哪里,最好放在它的父物体或者摄像机上比较靠谱,当然这个视情况而定,

实现读取Text文本,并存在字典里,方便根据ID查找信息的方法实现:
public TextAsset objectsInfoListText;
void ReadInfo()
{
string text = objectsInfoListText.text;
string[] strarray = text.Split('\n');
foreach(string str in strArray)
{
string[] proArray = str.Split(',');
ObjectInfo info = new ObjectINfo();
int id = int.Parse(proArray[0]);
string name = proArray[1];
}

}
创建一个字典的话,首先需要加入头文件:using System.Collections.Generic;
private Dictionary<int,ObjectInfo> objectInfoDict = new Dictionary<int,ObjectInfo>();

加入字典:objecyInfoDict.Add(id,info);//添加到字典中,id为key,info为信息,可以很方便的根据id很方便的查找到信息。

关于继承时候的Start和Update函数的使用:
在及成果后的类里面,我们需要先执行父类里面的Start和Update(如果用到的话,)函数,Base.Start(),Base.Update();然后再写自身类里面的代码。

如何让物品在物品栏里可以拖动:
首先,我们需要给每个物品的格子添加BoxCollider,然后让管理物品的脚本继承自UIDragDropItem,如果需要处理拖动后的事件:protected override void OnDragDropRelease(GameObject surface)
{
base.OnDragDropRelease(surface);//先调用父类的函数,防止掩盖。

}

在物品栏里产生物品:
NGUIToos.AddChild( , )它有连个参数,第一个是父物体,第二个是Prefab。
如果拖动后让物品位于物品栏格子的中心:
我们需要设置子物体相对于父物体的位置就可以了。设为0;
transform.localPosition = Vector3.zero;

如果物品加1,如何让物品栏格子的下标加1:
首先int 类型的num+1;让后让numLabel.text = this.num.ToString();

实现物品的拖拽功能:

protected override void OnDragDropRelease(GameObject surface) {
base.OnDragDropRelease(surface);
if (surface != null) {
if (surface.tag == Tags.inventory_item_grid) {//当拖放到了一个空的格子里面
if (surface == this.transform.parent.gameObject) {//拖放到了自己的格子里面

} else {
InventoryItemGrid oldParent = this.transform.parent.GetComponent<InventoryItemGrid>(); //得到老的方格。

this.transform.parent = surface.transform; ResetPosition(); //将这个物品放在接触到的(surface)下面,并且让相对位置归位,
InventoryItemGrid newParent = surface.GetComponent<InventoryItemGrid>(); //得到新的父类,
newParent.SetId(oldParent.id, oldParent.num); //在新的父类下面产生出一个一样的物品出来

oldParent.ClearInfo(); //并且清除老格子的信息。
}

} else if (surface.tag == Tags.inventory_item) {//当拖放到了一个有物品的格子里面,就交换两个格子里面的信息就行了。
InventoryItemGrid grid1 = this.transform.parent.GetComponent<InventoryItemGrid>();
InventoryItemGrid grid2 = surface.transform.parent.GetComponent<InventoryItemGrid>();
int id = grid1.id; int num = grid1.num;
grid1.SetId(grid2.id, grid2.num);
grid2.SetId(id, num);
} else if (surface.tag == Tags.shortcut) {//拖到的快捷方式里面
surface.GetComponent<ShortCutGrid>().SetInventory(id);
}

}

ResetPosition();
}

思路:物品交换的思路中的来说,先判断格子里是否有物品,如果没有,就在这个格子里面产生一个此物品就行了,如果放在了有物品的格子里面,如果物品相同,就让num+1;如果物品不同,就交换位子,即交换两个格子里面的物品信息显示就行了。

显示物品的基本信息:
首先我们给物品添加:,首先让物品上有Box Collider,添加UIEvent Listener脚本和UIEvent Trigger,然后我们可以在管理物品的脚本中写一个函数方法,拖到到OnHoberOver等事件监听的回调函数中,选择相应的方法就行了。

如何让物品信息显示框跟随鼠标移动:
我们让lable 的transform.position = UICamea.currentCamera.ScreenToWorldPoint(INput.MousePosition);
UICarmera.currentCamera是找到我们的UICamera的,然后根据ScreenToWorldPoint将鼠标的坐标转化为世界坐标。

解决TextAsset文件读取Bug:
首先将文本用记事本打开,点击另存为:当前路径,编码设置为UTF-8,保存覆盖。

添加头像:
我们在任务下面添加一个摄像机,然后添加一个Player层,将player的Layer层设置为Player,然后将相机的Culling Mask设置为Player,然后我们在工程视图中创建一个Render Texture。 然后将此摄像机的Target Texture设置为此Render Texture。然后在右上角添加产生一个simple Texture,然后将前面创建的render
texture指定过来,然后调整就行了,我们先导入一个Shader资源,然后创建一个Material,将Material的shader制定,然后指定Render Texture和Shader材质,然后为相机的Material 指定为这个。

小地图制作:
过程同添加头像一样;

设置NPC在小地图上的标识:
首先我们在NPC下创建一个Quad,然后为其添加图片,将Quad调整方位和大小到NPC的正上方,然后添加一个NPC层,设置Main Carmera不渲染NPC层,显示小地图
的相机渲染NPC层,当然要记得改变NPC的Layer;

实现小地图上的拉近和拉远:
我们在小地图的UI上创建两个Button按钮,为其添加脚本和方法,放在BUtton 的回调函数中,改变显示小地图的摄像机的orthographicSize的值;
放大就--,缩小就++;

显示MIss效果:
我们需要导入HDUText资源包,然后里面有一个HduText的Prefab,我们先为每一个需要的物体下增加一个HudText我们需要在产生它的时候调用自带方法:
HudText.Add("Miss",Color.gray,1);显示文字,文字颜色,显示时间;
当然前提还有很多准备工作,此处就不提了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: