【Unity3D自学记录】 Unity3D游戏开发之键盘选取、切换目标

▇ 知识点

  • GameObject.FindObjectsWithTag:获取带有指定Tag的多个游戏物体;
  • Input.GetKeyDown:检测指定按键是否按下;
  • (GameObject instance).renderer.material.color:修改这个参数使得对象的颜色变动,让目标是否选中效果更明显;
  • (GameObject instance).enabled:修改这个值使得对象是否可用/可见;

▇ 思路

  • 新建一个叫做Enemy的Tag,并设置到所有怪物上,我这里暂时只用Cube代替;
  • 新建一个Creature脚本,使其拥有单位名称、等级、生命、能量等属性,并附加给所有怪物后调整属性;
  • 新建一个Targeting脚本,附加到First Person Controller上,让玩家拥有选取目标的能力;
  • 在Targeting的Start方法中,用获取所有的敌人单位,维护到一个List中;
  • 在Targeting中,建立一个Creature成员变量,用来表示当前选中的目标生物;
  • 在Targeting的Update方法中,检测玩家按键,Tab用来选取下一个目标,Esc用来取消当前选中目标;
  • 用NGUI新建一个当前目标框体,并用脚本来显示当前目标的属性,当没有选择目标的时候,把目标框体隐藏掉;

▇ 脚本(Creature.cs)

[C#]  纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using UnityEngine;
using System.Collections;
 
/// <summary>
/// 生物组件
/// </summary>
public class Creature : MonoBehaviour
{
     /// <summary>
     /// 名称
     /// </summary>
     public string Name;
 
     /// <summary>
     /// 等级
     /// </summary>
     public int Level;
 
     /// <summary>
     /// 生命
     /// </summary>
     public float Health;
 
     /// <summary>
     /// 最大生命值
     /// </summary>
     public float MaxHealth;
 
     /// <summary>
     /// 能量
     /// </summary>
     public float Power;
 
     /// <summary>
     /// 最大能量值
     /// </summary>
     public float MaxPower;
 
     /// <summary>
     /// 经验值
     /// </summary>
     public float Exp;
 
     /// <summary>
     /// 最大经验值
     /// </summary>
     public float MaxExp;
 
     void Start()
     {
 
     }
 
     void Update()
     {
 
     }
}


▇ 脚本(Targeting.cs)


[C#]  纯文本查看 复制代码
?
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class Targeting : MonoBehaviour
{
     /// <summary>
     /// 目标列表
     /// </summary>
     public List<Creature> Targets;
 
     /// <summary>
     /// 当前目标
     /// </summary>
     public Creature CurrentTarget;
 
     void Start()
     {
         Targets = new List<Creature>();
         UpdateTargetList();
     }
 
     void Update()
     {
         if (Input.GetKeyDown(KeyCode.Tab))
         {
             //Tab键选中下一个目标
             SelectNextTarget();
         }
         else if (Input.GetKeyDown(KeyCode.Escape))
         {
             //Esc键取消当前目标
             CancelSelection();
         }
     }
 
     /// <summary>
     /// 更新目标列表
     /// </summary>
     public void UpdateTargetList()
     {
         //更新所有带Enemy标记的游戏对象到Targets列表
         Targets.Clear();
         var gameObjects = GameObject.FindGameObjectsWithTag( "Enemy" );
         foreach (var obj in gameObjects)
         {
             var creature = obj.GetComponent<Creature>();
             if (creature != null )
                 Targets.Add(creature);
         }
     }
 
     /// <summary>
     /// 选择下一个目标
     /// </summary>
     public void SelectNextTarget()
     {
         //没有可选目标,放弃选择
         if (Targets.Count == 0)
             return ;
 
         //当前没有目标,取第一个作为目标
         if (CurrentTarget == null )
         {
             CurrentTarget = Targets[0];
         }
         else
         {
             hideSelectionEffect();
             //若当前目标不在当前目标列表中,或者是列表中的最后一个,取第一个作为目标,否则取列表中的下一个目标
             var index = Targets.IndexOf(CurrentTarget);
             if (index < 0 || index == Targets.Count - 1)
             {
                 CurrentTarget = Targets[0];
             }
             else
             {
                 CurrentTarget = Targets[index + 1];
             }
         }
         showSelectionEffect();
     }
 
     /// <summary>
     /// 取消选择目标
     /// </summary>
     public void CancelSelection()
     {
         hideSelectionEffect();
         CurrentTarget = null ;
     }
 
     private void showSelectionEffect()
     {
         if (CurrentTarget != null )
             CurrentTarget.renderer.material.color = Color.red;
     }
     private void hideSelectionEffect()
     {
         if (CurrentTarget != null )
             CurrentTarget.renderer.material.color = Color.white;
     }
}


▇ 脚本(TargetPortrait.cs)


[C#]  纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
using UnityEngine;
using System.Collections;
 
public class TargetPortrait : MonoBehaviour
{
     /// <summary>
     /// 目标名称标签
     /// </summary>
     public UILabel NameLabel;
 
     /// <summary>
     /// 等级标签
     /// </summary>
     public UILabel LevelLabel;
 
     /// <summary>
     /// 生命条
     /// </summary>
     public UISlider HealthBar;
 
     /// <summary>
     /// 能量条
     /// </summary>
     public UISlider PowerBar;
 
     /// <summary>
     /// 目标框体
     /// </summary>
     public UIPanel UIRoot;
 
     private Targeting m_TargetingComponent;
 
     void Start()
     {
         var player = GameObject.FindGameObjectWithTag( "Player" );
         m_TargetingComponent = player.GetComponent<Targeting>();
     }
 
     void Update()
     {
         if (m_TargetingComponent.CurrentTarget == null )
         {
             UIRoot.enabled = false ;
         }
         else
         {
             UIRoot.enabled = true ;
             var target = m_TargetingComponent.CurrentTarget;
             NameLabel.text = target.Name;
             LevelLabel.text = target.Level.ToString();
             HealthBar.sliderValue = target.Health / target.MaxHealth;
             PowerBar.sliderValue = target.Power / target.MaxPower;
         }
     }
}


▇ 效果


img.png (480.89 KB, 下载次数: 0)

下载附件  保存到相册

2013-6-30 13:04 上传


按Tab键选中目标后,对应的Cube就会变红。按Esc则会取消选中的目标,原来变红的Cube全会变白。在《Hack & Slash RPG》教学视频中还做了优先按距离选取最近的那个目标,原理也很简单,就是用Vector3.Distance求两点间的距离,在修改当前目标前先将目标列表按距离排序就可以了。在魔兽世界里效果就更帅气了,目标底下会有个光圈。不过我的制作思路还不是很清晰,就先放一放,应该不会太难

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值