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

来源:互联网 发布:四选一数据选择器芯片 编辑:程序博客网 时间:2024/05/16 05:26

▇ 知识点

  • 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
usingUnityEngine;
usingSystem.Collections;
 
/// <summary>
/// 生物组件
/// </summary>
publicclass Creature : MonoBehaviour
{
    /// <summary>
    /// 名称
    /// </summary>
    publicstring Name;
 
    /// <summary>
    /// 等级
    /// </summary>
    publicint Level;
 
    /// <summary>
    /// 生命
    /// </summary>
    publicfloat Health;
 
    /// <summary>
    /// 最大生命值
    /// </summary>
    publicfloat MaxHealth;
 
    /// <summary>
    /// 能量
    /// </summary>
    publicfloat Power;
 
    /// <summary>
    /// 最大能量值
    /// </summary>
    publicfloat MaxPower;
 
    /// <summary>
    /// 经验值
    /// </summary>
    publicfloat Exp;
 
    /// <summary>
    /// 最大经验值
    /// </summary>
    publicfloat MaxExp;
 
    voidStart()
    {
 
    }
 
    voidUpdate()
    {
 
    }
}


▇ 脚本(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
usingUnityEngine;
usingSystem.Collections;
usingSystem.Collections.Generic;
 
publicclass Targeting : MonoBehaviour
{
    /// <summary>
    /// 目标列表
    /// </summary>
    publicList<Creature> Targets;
 
    /// <summary>
    /// 当前目标
    /// </summary>
    publicCreature CurrentTarget;
 
    voidStart()
    {
        Targets = newList<Creature>();
        UpdateTargetList();
    }
 
    voidUpdate()
    {
        if(Input.GetKeyDown(KeyCode.Tab))
        {
            //Tab键选中下一个目标
            SelectNextTarget();
        }
        elseif (Input.GetKeyDown(KeyCode.Escape))
        {
            //Esc键取消当前目标
            CancelSelection();
        }
    }
 
    /// <summary>
    /// 更新目标列表
    /// </summary>
    publicvoid UpdateTargetList()
    {
        //更新所有带Enemy标记的游戏对象到Targets列表
        Targets.Clear();
        var gameObjects = GameObject.FindGameObjectsWithTag("Enemy");
        foreach(var obj ingameObjects)
        {
            var creature = obj.GetComponent<Creature>();
            if(creature != null)
                Targets.Add(creature);
        }
    }
 
    /// <summary>
    /// 选择下一个目标
    /// </summary>
    publicvoid 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>
    publicvoid CancelSelection()
    {
        hideSelectionEffect();
        CurrentTarget = null;
    }
 
    privatevoid showSelectionEffect()
    {
        if(CurrentTarget != null)
            CurrentTarget.renderer.material.color = Color.red;
    }
    privatevoid 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
usingUnityEngine;
usingSystem.Collections;
 
publicclass TargetPortrait : MonoBehaviour
{
    /// <summary>
    /// 目标名称标签
    /// </summary>
    publicUILabel NameLabel;
 
    /// <summary>
    /// 等级标签
    /// </summary>
    publicUILabel LevelLabel;
 
    /// <summary>
    /// 生命条
    /// </summary>
    publicUISlider HealthBar;
 
    /// <summary>
    /// 能量条
    /// </summary>
    publicUISlider PowerBar;
 
    /// <summary>
    /// 目标框体
    /// </summary>
    publicUIPanel UIRoot;
 
    privateTargeting m_TargetingComponent;
 
    voidStart()
    {
        var player = GameObject.FindGameObjectWithTag("Player");
        m_TargetingComponent = player.GetComponent<Targeting>();
    }
 
    voidUpdate()
    {
        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 0
原创粉丝点击