unity【动画】脚本_角色动画控制器 c#

首先创建一个代码文件夹Scripts

从人物角色Player的基类开始   创建IPlayer类

首先我们考虑到如果不挂载MonoBehaviour需要将角色设置成预制体实例化到场景上十分麻烦,

所以我们采用继承MonoBehaviour类的角色基类方法写代码

也就是说这个脚本直接绑定在角色物体身上,就不需要实例化了,相对降低了复杂程度。

首先我们需要在unity场景制作一个Renderer类型的目标点

首先创建一个平面Plane改名为MovementTargetSign

修改位置

移除掉碰撞器

添加一个材质 

对材质进行修改 点击Shader选项

选择一个纹理

代码:

using UnityEngine;
//抽象角色类-包括玩家和NPC
public class IPlayer : MonoBehaviour{
    protected Animator _animator;//动画器组件引用
    private IWeapon _weapon = null;//武器的引用
}

public class IWeapon{

}

using UnityEngine;
public class Player : IPlayer{
    private Renderer movementSign;//移动标志
    private Collider attackPlane;//攻击区
    private Collider floorPlane;//普通地面(非攻击区)
    private Vector3 lookatPos;//面向位置
    private float rotSpeed = 20f;//移动旋转速度
    private float attackRotSpeed = 10f;//攻击旋转速度
}

public class FemaleWarrior : Player{

}
将FemaleWarrior代码挂载Player对象身上

对角色Player添加胶囊碰撞器

调整胶囊碰撞器位于角色中心

再添加刚体

关掉 使用重力Use Gravity 勾选

在约束上constraints 冻结旋转 x y z

如果制作的角色不需要重力则用碰撞器实现,

如果制作的角色需要重力    则用刚体   实现

先用刚体实现:

代码如下:

using UnityEngine;
//抽象角色类-包括玩家和NPC
public class IPlayer : MonoBehaviour{
    protected Animator _animator;//动画器组件引用
    private IWeapon _weapon = null;//武器的引用
}

public class IWeapon{

}

using UnityEngine;
public class Player : IPlayer{
    private Renderer movementSign;//移动标志
    private Collider attackPlane;//攻击区
    private Collider floorPlane;//普通地面(非攻击区)
    private Vector3 lookatPos;//面向位置
    private float rotSpeed = 20f;//移动旋转速度
    private float attackRotSpeed = 10f;//攻击旋转速度
    protected virtual void Awake() {
        //移动标志
        if (movementSign == null)
            movementSign = GameObject.Find("MovementTargetSign").GetComponent<Renderer>();
    }
    protected virtual void Start(){
        //移动标志默认放在玩家脚下
        movementSign.transform.position = transform.position + new Vector3(0,0.02f,0);
        movementSign.enabled = false;//关闭移动标志的显示
    }
    //跟随鼠标旋转
    public void RotateWithCursorPos() {
        RaycastHit hit;
        //构建一条从摄像机到鼠标位置的射线
        var Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(Ray, out hit)) {
            //计算方向
            Vector3 mousePos = new Vector3(hit.point.x, transform.position.y, hit.point.z);
            Vector3 playerDirection = mousePos - transform.position;
            if (playerDirection != Vector3.zero) {
                //旋转到目标方向
                transform.rotation = Quaternion.Slerp(transform.rotation,
                    Quaternion.LookRotation(playerDirection), Time.deltaTime * attackRotSpeed);
            }
        }
    }
    protected virtual void Update() {
        RotateWithCursorPos();
    }
}

public class FemaleWarrior : Player{
    protected override void Awake(){
        base.Awake();
    }
    protected override void Start(){
        base.Start();
    }
}
完成人物转向之后,开始做人物移动功能

首先添加代码,将动画机参数转换为哈希值

using UnityEngine;
public class AnimaterConsteantVelues {
    public static int WeaponID = Animator.StringToHash("WeaponID");
    public static int isCombat = Animator.StringToHash("isCombat");
    public static int isIdle = Animator.StringToHash("isIdle");
    public static int Attack = Animator.StringToHash("Attack");
}
在角色基类中添加函数

using UnityEngine;
//抽象角色类-包括玩家和NPC
public class IPlayer : MonoBehaviour{
    protected Animator _animator;//动画器组件引用
    private IWeapon _weapon = null;//武器的引用
    public IWeapon Weapon {
        get => _weapon;
        set => _weapon = value;
    }
    public void Attack() {
        if (_weapon != null)
            _weapon.Attack();
    }
}
修改抽象武器基类

using UnityEngine;
public abstract class IWeapon{
    public string WeaponName { get; set; }
    protected GameObject _weaponModel;
    protected GameObject _weaponPrefab;
    private int weaponID { get; set; }
    protected IPlayer _player { get; set; }
    public GameObject WeaponPrefab {
        get => _weaponModel; 
        set => _weaponModel = value;
    }
    public virtual void Attack() { }
    public virtual void RefreshLine() { }
    public IWeapon(int weaponID, string name, string weaponModelPath, IPlayer player){
        this.weaponID = weaponID;
        WeaponName = name;
        _player = player;
        if (weaponModelPath != "") {
            _weaponModel = Resources.Load<GameObject>(weaponModelPath);
            if (_weaponModel != null) {
                var weaponPos = ((Player)_player).handleWeaponPosList[weaponID];
                _weaponPrefab = GameObject.Instantiate(_weaponModel, weaponPos.position, weaponPos.rotation);
                _weaponPrefab.transform.SetParent(weaponPos);
                _weaponPrefab.SetActive(false);
            }
        }
    }
}
修改角色子类

using System.Collections.Generic;
using UnityEngine;
public class Player : IPlayer{
    private Renderer movementSign;//移动标志
    private Collider attackPlane;//攻击区
    private Collider floorPlane;//普通地面(非攻击区)
    private Vector3 lookatPos;//面向位置
    private float rotSpeed = 20f;//移动旋转速度
    private float attackRotSpeed = 10f;//攻击旋转速度
    private float fallSpeed;
    //列表
    [SerializeField]
    public List<Transform>handleWeaponPosList = new List<Transform>();
    protected virtual void Awake() {
        _animator = GetComponent<Animator>();
        floorPlane = GameObject.Find("Plane").GetComponent<Collider>();
        //移动标志
        if (movementSign == null)
            movementSign = GameObject.Find("MovementTargetSign").GetComponent<Renderer>();
    }
    protected virtual void Start(){
        //移动标志默认放在玩家脚下
        movementSign.transform.position = transform.position + new Vector3(0,2f,0);
        movementSign.enabled = false;//关闭移动标志的显示
    }
    //跟随鼠标旋转
    public void RotateWithCursorPos() {
        RaycastHit hit;
        //构建一条从摄像机到鼠标位置的射线
        var Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(Ray, out hit)) {
            //计算方向
            Vector3 mousePos = new Vector3(hit.point.x, transform.position.y, hit.point.z);
            Vector3 playerDirection = mousePos - transform.position;
            if (playerDirection != Vector3.zero) {
                //旋转到目标方向
                transform.rotation = Quaternion.Slerp(transform.rotation,
                    Quaternion.LookRotation(playerDirection), Time.deltaTime * attackRotSpeed);
            }
        }
    }
    public void Move(){
        RaycastHit hit;
        var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Input.GetMouseButton(0)){
            if (floorPlane.Raycast(ray, out hit, 50f)){
                movementSign.transform.position = hit.point + new Vector3(0, 0.01f, 0);
                movementSign.enabled = true;
                lookatPos = hit.point;
            }
        }
        else if(Input.GetMouseButtonUp(1)){
            _animator.SetBool(AnimaterConsteantVelues.isCombat, true);
            _animator.SetTrigger(AnimaterConsteantVelues.Attack);
            Attack();
        }
        lookatPos.y = transform.position.y;
        var playerDirection = lookatPos - transform.position;
        if (playerDirection != Vector3.zero) 
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(playerDirection), Time.deltaTime * rotSpeed);
        var offset = movementSign.transform.position - transform.position;
        var sqrDistance = offset.sqrMagnitude;
        if (sqrDistance > 0.1f){
            _animator.SetBool(AnimaterConsteantVelues.isIdle, false);
            rotSpeed = 20f;
        }
        else {
            _animator.SetBool(AnimaterConsteantVelues.isIdle,true);
            movementSign.enabled = false;
            movementSign.transform.position = transform.position;
            rotSpeed = 0;
        }
        var bodyRay = new Ray(transform.position + transform.up, transform.up * -1);
        if (floorPlane.Raycast(bodyRay, out hit, 1.0f)) {
            if (hit.point.y > transform.position.y + 0.02f)
                transform.position = hit.point + new Vector3(0, 0.02f, 0);
            else if (floorPlane.Raycast(bodyRay, out hit, 1.2f))
                if (hit.point.y > transform.position.y - 0.02f) 
                    transform.position = hit.point + new Vector3(0, -0.02f, 0);
            else {
                fallSpeed += 0.1f;
                var v = new Vector3(0, fallSpeed * Time.deltaTime, 0);
                transform.position -= v;
                movementSign.transform.position = transform.position + new Vector3(0, 0.01f, 0);
            }
        }
    }
    protected virtual void Update() {
        RotateWithCursorPos();
        Move();
    }
}

回到Unity场景中拖拽填充武器刷新

人物移动完成

接下来完成背包系统 

放进预制体包后完全解压缩

调整好Slot0-4的背景位置,将四个子物体预制体包后删除

子物体位置都改成0

隐藏/取消激活

接下来完成拾取道具

加碰撞器

调节碰撞器

加触发器

加刚体

修改名字

创建脚本

using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//可拾取道具
public class CanPickupItem : MonoBehaviour{
    public AudioClip pickUpSound;//拾取声音
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player")) {
            //播放声音
            if (pickUpSound != null)
                AudioSource.PlayClipAtPoint(pickUpSound,transform.position);
            //将本道具更新到背包列表中
            GameObject.FindGameObjectWithTag("InventoryUITag").GetComponent<InventoryManager>().ItemNames.Add(gameObject.name);
            Destroy(gameObject);

        }
    }
}
 

挂载脚本

同样挂载到手枪上

添加标签

创建脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class InventoryManager : MonoBehaviour
{
    //道具名称列表
    public List<string> ItemNames = new List<string>();

}
 

给人物标签

标签

运行即可触发拾取道具

接下来做背包系统

首先这里不用字典代码,运用简单方式制作,前提必须保证道具 和 道具图片的英文名字存在包含关系

在管理类中写一个打开背包的方法

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class InventoryManager : MonoBehaviour
{
    //道具名称列表
    public List<string> ItemNames = new List<string>();
    //打开或关闭背包
    public void OpenOrCloseInventoryUI(bool isOpen) {
        transform.Find("Panel").gameObject.SetActive(isOpen);
    }
}

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting.Antlr3.Runtime;
using UnityEngine;
using UnityEngine.UI;

public class InventoryManager : MonoBehaviour
{
    //道具名称列表
    public List<string> ItemNames = new List<string>();
    //是否显示背包UI
    private bool isShowInventoryUI = false;
    //打开或关闭背包
    public void OpenOrCloseInventoryUI(bool isOpen) {
        transform.Find("Panel").gameObject.SetActive(isOpen);
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.B)) {
            isShowInventoryUI = !isShowInventoryUI;
            //打开或关闭UI
            OpenOrCloseInventoryUI(isShowInventoryUI);
        }
    }
}

即可实现背包按B键开关背包UI

接下来我们需要做一个背包图标的UI,点击UI也能打开背包

即完成鼠标点击显隐背包UI 及 键盘B键显隐背包UI

接下来做UI文本更新,意义不大可省略,存在的意义在于完善体系

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class InventoryManager : MonoBehaviour{
    //道具名称列表
    public List<string> ItemNames = new List<string>();
    //是否显示背包UI
    private bool isShowInventoryUI = false;
    //UI界面中的文本
    public Text[] textUI;
    //激活或关闭背包UI显示
    public void OpenOrCloseInventoryUI(bool isOpen) {
        transform.Find("Panel").gameObject.SetActive(isOpen);
        //更新文本
        UpdateInventoryTextUI();
    }
    private void Update(){
        if (Input.GetKeyDown(KeyCode.B))
            InventoryUIState();
    }
    //打开或关闭背包
    public void InventoryUIState() {
        isShowInventoryUI = !isShowInventoryUI;
        //打开或关闭UI
        OpenOrCloseInventoryUI(isShowInventoryUI);
    }
    //更新文本UI 
    private void UpdateInventoryTextUI(){
        for(int i = 0;i< ItemNames.Count;i++)
            textUI[i].text = ItemNames[i];
    }
}

调整文本在背包UI中的位置

取消激活面板

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class InventoryManager : MonoBehaviour{
    public List<string> ItemNames = new List<string>();//道具名称列表
    private bool isShowInventoryUI = false;//是否显示背包UI
    public Text[] textUI;//UI界面中的文本
    public Image[] availableItemIcons;//可以获取的道具图标
    public void OpenOrCloseInventoryUI(bool isOpen){//激活或关闭背包UI显示
        transform.Find("Panel").gameObject.SetActive(isOpen);
        UpdateInventoryTextUI(); //更新文本
        UpdateInventoryIconUI();//更新图标
    }
    private void Update(){
        if (Input.GetKeyDown(KeyCode.B))
            InventoryUIState();
    }
    public void InventoryUIState(){//打开或关闭背包
        isShowInventoryUI = !isShowInventoryUI;
        OpenOrCloseInventoryUI(isShowInventoryUI);//打开或关闭UI
    }
    private void UpdateInventoryTextUI(){//更新文本UI 
        for (int i = 0;i < ItemNames.Count;i++)
            textUI[i].text = ItemNames[i];
    }
    private void UpdateInventoryIconUI(){//更新图标UI
        for (int i = 0; i < ItemNames.Count; i++){
            Image itemIcon = GetIconPrefabByItemName(ItemNames[i]);//根据道具名称返回对应的图标
            if (itemIcon != null){
                Image newItemIcon = Instantiate(itemIcon);//将图标克隆到对应的Image中
                newItemIcon.transform.SetParent(textUI[i].transform.parent);//更改父物体
                RectTransform rt = newItemIcon.GetComponent<RectTransform>();//调整位置
                rt.anchoredPosition = Vector3.zero;
            }
            else
                Debug.LogError("没找到对应图标");
        }
    }
    private Image GetIconPrefabByItemName(string name){//根据道具名称返回对应的图标
        for (int i = 0; i < availableItemIcons.Length; i++){
            if (availableItemIcons[i].name.Contains(name))
                return availableItemIcons[i];
        }
        return null;
    }
}

隐藏文字部分

运行即完成

挂移动摄像机

using UnityEngine;
public class CameraMove : MonoBehaviour{ //第三人称摄像机简单版
    public Transform target;//摄像机的跟随目标
    public float distance = 8.0f;//摄像机与目标之间的距离
    private float x, y, z;
    private float xSpeed = 250.0f;
    private float ySpeed = 120.0f;
    public float yMinlimit = -45.0f;//限制上下移动角度
    public float yMaxlimit = 45.0f;
    private void Awake(){
        //注册场景加载完毕事件
        //EventCenter.AddListener(EventType.SceneLoadComplete, SetTarget);
    }
    private void SetTarget(){
        //将标签为Player的物体设置为跟踪目标
        Transform player = GameObject.FindGameObjectWithTag("Player").transform;
        if (player != null && target == null)
            target = player;
    }
    private void Start(){
        Vector3 angles = transform.eulerAngles;//获取摄像机的当前角度
        x = angles.x;
        y = angles.y;
        z = -distance;
        GoRight();
    }

    private void LateUpdate(){
        float temp = Input.GetAxis("Mouse ScrollWheel");//获取滚轮数值
        if (target != null){
            if (Input.GetMouseButton(0)){
                x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
                y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
            }
        }
        //钳制上下移动的角度
        y = ClampAngle(y,yMinlimit,yMaxlimit);
        z += temp * 100f * 0.02f;//数值按照自己喜好设定
        z = Mathf.Clamp(z,-20f,-3.0f);//距离限制,最远是距离玩家20米,最近是3米
        GoRight();//作用于摄像机
    }
    float ClampAngle(float angle,float min,float max){
        if (angle < -360)
            angle += 360;
        if (angle > 360)
            angle -= 360;
        return Mathf.Clamp(angle,min,max);
    }
    //摄像机控制位置及角度的核心方法
    void GoRight(){
        if (target == null)
            return;
        Quaternion rotation = Quaternion.Euler(y,x,0);//摄像机角度
        Vector3 position = rotation * new Vector3(0.0f,0.0f,z)+target.position;
        transform.position = position;//摄像机位置
        transform.rotation = rotation;//摄像机角度
    }
}

即完成摄像机跟随人物移动

接下来做捡起道具穿戴到后背及手中

首先

设置好之后隐藏pos

同样做一个手里的pos

修改拾取代码

using UnityEngine;
//可拾取道具
public class CanPickupItem : MonoBehaviour{
    public AudioClip pickUpSound;//拾取声音
    private void OnTriggerEnter(Collider other){
        if (other.CompareTag("Player")){
            //判断绑定脚本的可交互道具是什么
            switch (gameObject.name) {
                case "Weapon1":
                    //将武器1从地面转移到玩家背上
                    //找到武器1在玩家背上的坐标物体
                    Transform weapon1Pos = GameObject.FindGameObjectWithTag("Weapon1Pos").transform;
                    //修改步枪的位置及角度,与坐标物体对齐
                    transform.position = weapon1Pos.position;
                    transform.rotation = weapon1Pos.rotation;
                    //将武器2的父物体改为后背的武器2坐标
                    transform.SetParent(weapon1Pos);
                    //关闭武器2的碰撞器
                    gameObject.GetComponent<BoxCollider>().enabled = false;
                    //关闭触发器
                    gameObject.GetComponent<SphereCollider>().enabled = false;
                    //打开忽略物理学运算开关
                    gameObject.GetComponent<Rigidbody>().isKinematic = true;
                    break;
                case "Weapon2":
                    //将武器1从地面转移到玩家背上
                    //找到武器1在玩家背上的坐标物体
                    Transform weapon2Pos = GameObject.FindGameObjectWithTag("Weapon2Pos").transform;
                    //修改步枪的位置及角度,与坐标物体对齐
                    transform.position = weapon2Pos.position;
                    transform.rotation = weapon2Pos.rotation;
                    //将武器2的父物体改为后背的武器2坐标
                    transform.SetParent(weapon2Pos);
                    //关闭武器2的碰撞器
                    gameObject.GetComponent<BoxCollider>().enabled = false;
                    //关闭触发器
                    gameObject.GetComponent<SphereCollider>().enabled = false;
                    //打开忽略物理学运算开关
                    gameObject.GetComponent<Rigidbody>().isKinematic = true;
                    break;
            }
            //播放声音
            if (pickUpSound != null)
                AudioSource.PlayClipAtPoint(pickUpSound, transform.position);
            //将本道具更新到背包列表中
            GameObject.FindGameObjectWithTag("InventoryUITag").GetComponent<InventoryManager>().ItemNames.Add(gameObject.name);
            //Destroy(gameObject);
        }
    }
}
运行即拾取道具即可穿戴在身上

接下来我们做道具装备得使用,本次做法是将背包中的格子imae预制体都变成button,点击后就相当于点击了按钮,image与button之间只差了一个组件button组件加上即从image变成了按钮

接下来创建库存使用代码

挂载到预制体变成button得image上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InventoryItemUse : MonoBehaviour
{
    //道具图标点击
    public void OnItemIconClicked() {
        string itemName = gameObject.name;
        print(itemName);
    }
}
双击button1进入到预制体空间

新建一个事件

接下来做个可拖动窗口,挂载在背包UI上运行即可鼠标拖拽窗口

创建一个脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
//拖动UI窗口
public class DraggableWindow : MonoBehaviour,IPointerDownHandler,IDragHandler
{
    private Vector2 offest;//偏移量
    public void OnPointerDown(PointerEventData eventData)
    {
        offest = (Vector2)transform.position - eventData.position;  
    }
    public void OnDrag(PointerEventData eventData)
    {
        transform.position = eventData.position + offest;
    }
}
挂载到背包Panel脚本上

运行即可实现背包可拖动化

接下来做打开关闭背包后禁用人物移动和转换视角功能

首先

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
public class InventoryManager : MonoBehaviour
{
    //道具名称列表
    public List<string> ItemNames = new List<string>();
    //是否显示背包UI
    private bool isShowInventoryUI = false;
    //UI界面中的Text
    public Text[] textUI;
    //可以获取的道具图标集合
    public Image[] availableItemIcons;
    //背包打开事件
    public UnityEvent OpenIventoryUIEvent;
    //背包关闭事件
    public UnityEvent CloseIventoryUIEvent;
    //激活或关闭背包面板
    public void OpenOrCloseInventoryUI(bool isOpen)
    {
        transform.Find("Panel").gameObject.SetActive(isOpen);
        UpdateInventoryTextUI();//更新文本
        UpdateInventoryIconUI();//更新图标
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.B))
        {
            InventoryUIState();
        }
    }
    //开关或关闭背包
    public void InventoryUIState()
    {
        isShowInventoryUI = !isShowInventoryUI;
        //打开或关闭UI
        OpenOrCloseInventoryUI(isShowInventoryUI);
        if (isShowInventoryUI)
        {
            if (OpenIventoryUIEvent != null)
                OpenIventoryUIEvent.Invoke();
        }
        else
            CloseIventoryUIEvent?.Invoke();
    }
    //更新文本UI
    private void UpdateInventoryTextUI()
    {
        for (int i = 0; i < ItemNames.Count; i++)
        {
            textUI[i].text = ItemNames[i];
        }
    }
    //更新图标UI
    private void UpdateInventoryIconUI()
    {
        for (int i = 0; i < ItemNames.Count; i++)
        {
            //根据道具名称返回对应的图标
            Image itemIcon = GetIconPrefabByItemName(ItemNames[i]);
            if (itemIcon != null)
            {
                //将图标克隆到对应的solt中
                Image newItemIcon = Instantiate(itemIcon);
                //更改父物体
                newItemIcon.transform.SetParent(textUI[i].transform.parent);
                //调整位置
                RectTransform rt = newItemIcon.GetComponent<RectTransform>();
                rt.anchoredPosition = Vector3.zero;
            }
            else
            {
                Debug.LogError("没找到对应图标");
            }
        }
    }
    //根据道具名称返回对应的图标
    private Image GetIconPrefabByItemName(string name)
    {
        for (int i = 0; i < availableItemIcons.Length; i++)
        {
            if (availableItemIcons[i].name.Contains(name))
                return availableItemIcons[i];
        }
        return null;
    }
}

此时运行,人物打开背包后就不可以行走了

同样操作

这样关闭背包可以移动了

同样做法,做打开背包后禁用鼠标转换视角

运行即可实现,打开背包后 不能移动且不能转换视角,关闭背包后恢复正常

再创建一个脚本玩家装配得道具

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerCarryItem : MonoBehaviour
{
    //public List<GameObject> carryItemList = new List<GameObject>();
    //道具字典 记录图标名称和对应模型
    public Dictionary<string,GameObject> carryItemDict = new Dictionary<string, GameObject>();

}
修改InventoryItemUse代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InventoryItemUse : MonoBehaviour
{
    //道具图标点击
    public void OnItemIconClicked() {
        string itemTag = gameObject.tag;
        print(gameObject.name);
        switch (itemTag) {
            case "Weapon1_r":
                CanEquipedWeapon();
                break;
        }
    }
    //可被装备的武器
    private void CanEquipedWeapon() {
        //显示在玩家手上
        //进入武器装备栏
    }


    //根据名称返回图形
    private GameObject GetPrefabByIconName(string name)
    {
        GameObject prefab = null;

        return null;
    }
}
修改CanPickuoItem代码

using UnityEngine;
//可拾取道具
public class CanPickupItem : MonoBehaviour{
    public AudioClip pickUpSound;//拾取声音
    private void OnTriggerEnter(Collider other){
        if (other.CompareTag("Player")){
            //判断绑定脚本的可交互道具是什么
            switch (gameObject.name) {
                case "Weapon1":
                    MoveToItem("Weapon1Pos");
                    break;
                case "Weapon2":
                    MoveToItem("Weapon2Pos");
                    break;
            }
            //播放声音
            if (pickUpSound != null)
                AudioSource.PlayClipAtPoint(pickUpSound, transform.position);
            //将本道具更新到背包列表中
            GameObject.FindGameObjectWithTag("InventoryUITag").GetComponent<InventoryManager>().ItemNames.Add(gameObject.name);
            //Destroy(gameObject);
            //将道具模型添加到玩家背包中
            GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerCarryItem>().carryItemDict.Add("null", gameObject);
        }
    }
    private void MoveToItem(string tagName) {
        //将武器1从地面转移到玩家背上
        //找到武器1在玩家背上的坐标物体
        Transform weapon1Pos = GameObject.FindGameObjectWithTag(tagName).transform;
        //修改步枪的位置及角度,与坐标物体对齐
        transform.position = weapon1Pos.position;
        transform.rotation = weapon1Pos.rotation;
        //将武器2的父物体改为后背的武器2坐标
        transform.SetParent(weapon1Pos);
        //关闭武器2的碰撞器
        gameObject.GetComponent<BoxCollider>().enabled = false;
        //关闭触发器
        gameObject.GetComponent<SphereCollider>().enabled = false;
        //打开忽略物理学运算开关
        gameObject.GetComponent<Rigidbody>().isKinematic = true;
    }
}

修改CanPickuoItem代码

using UnityEngine;
//可拾取道具
public class CanPickupItem : MonoBehaviour{
    public AudioClip pickUpSound;//拾取声音
    private void OnTriggerEnter(Collider other){
        if (other.CompareTag("Player")){
            //判断绑定脚本的可交互道具是什么
            switch (gameObject.name) {
                case "Weapon1":
                    MoveToItem("Weapon1Pos");
                    break;
                case "Weapon2":
                    MoveToItem("Weapon2Pos");
                    break;
            }
            //播放声音
            if (pickUpSound != null)
                AudioSource.PlayClipAtPoint(pickUpSound, transform.position);
            //将本道具更新到背包列表中
            GameObject.FindGameObjectWithTag("InventoryUITag").
                GetComponent<InventoryManager>().ItemNames.Add(gameObject.name);
            //Destroy(gameObject);
            //将道具模型添加到玩家背包中
            GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerCarryItem>().
                carryItemDict.Add(GetIconNameByItemName(gameObject.name), gameObject);
        }
    }
    //根据道具名称返回图标名称
    private string GetIconNameByItemName(string itemName) {
        string iconName = "Icon_" + itemName;
        return iconName;
    }

    //转移到玩家身上
    private void MoveToItem(string tagName) {
        //将武器1从地面转移到玩家背上
        //找到武器1在玩家背上的坐标物体
        Transform weapon1Pos = GameObject.FindGameObjectWithTag(tagName).transform;
        //修改步枪的位置及角度,与坐标物体对齐
        transform.position = weapon1Pos.position;
        transform.rotation = weapon1Pos.rotation;
        //将武器2的父物体改为后背的武器2坐标
        transform.SetParent(weapon1Pos);
        //关闭武器2的碰撞器
        gameObject.GetComponent<BoxCollider>().enabled = false;
        //关闭触发器
        gameObject.GetComponent<SphereCollider>().enabled = false;
        //打开忽略物理学运算开关
        gameObject.GetComponent<Rigidbody>().isKinematic = true;
    }
}
修改代码增添调试语句

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerCarryItem : MonoBehaviour
{
    //public List<GameObject> carryItemList = new List<GameObject>();
    //道具字典 记录图标名称和对应模型
    public Dictionary<string,GameObject> carryItemDict = new Dictionary<string, GameObject>();
    //调试语句
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.P)) {
            foreach (var item in carryItemDict) {
                print("Key:" + item.Key + "Value:" + item.Value);
            }
        }
    }
}
挂载代码

运行吃道具后按P即可输出调试语句

修改代码

using UnityEngine;
//可拾取道具
public class CanPickupItem : MonoBehaviour{
    public AudioClip pickUpSound;//拾取声音
    private void OnTriggerEnter(Collider other){
        if (other.CompareTag("Player")){
            //判断绑定脚本的可交互道具是什么
            switch (gameObject.name) {
                case "Weapon1":
                    MoveToItem("Weapon1Pos");
                    break;
                case "Weapon2":
                    MoveToItem("Weapon2Pos");
                    break;
            }
            //播放声音
            if (pickUpSound != null)
                AudioSource.PlayClipAtPoint(pickUpSound, transform.position);
            //将本道具更新到背包列表中
            GameObject.FindGameObjectWithTag("InventoryUITag").
                GetComponent<InventoryManager>().ItemNames.Add(gameObject.name);
            //Destroy(gameObject);
            //将道具模型添加到玩家背包中
            GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerCarryItem>().
                carryItemDict.Add(GetIconNameByItemName(gameObject.name), gameObject);
        }
    }
    //根据道具名称返回图标名称
    private string GetIconNameByItemName(string itemName) {
        string iconName = "Icon_" + itemName + "(Clone)";
        return iconName;
    }

    //转移到玩家身上
    private void MoveToItem(string tagName) {
        //将武器1从地面转移到玩家背上
        //找到武器1在玩家背上的坐标物体
        Transform weapon1Pos = GameObject.FindGameObjectWithTag(tagName).transform;
        //修改步枪的位置及角度,与坐标物体对齐
        transform.position = weapon1Pos.position;
        transform.rotation = weapon1Pos.rotation;
        //将武器2的父物体改为后背的武器2坐标
        transform.SetParent(weapon1Pos);
        //关闭武器2的碰撞器
        gameObject.GetComponent<BoxCollider>().enabled = false;
        //关闭触发器
        gameObject.GetComponent<SphereCollider>().enabled = false;
        //打开忽略物理学运算开关
        gameObject.GetComponent<Rigidbody>().isKinematic = true;
    }
}
修改代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InventoryItemUse : MonoBehaviour
{
    //图标名称
    private string iconName;
    //道具图标点击
    public void OnItemIconClicked() {
        string itemTag = gameObject.tag;
        //图标名称
        print(gameObject.name);
        switch (itemTag) {
            case "Weapon1_r":
                CanEquipedWeapon();
                break;
        }
    }
    //可被装备的武器
    private void CanEquipedWeapon() {
        //显示在玩家手上
        print(GetPrefabByIconName(iconName));
        //进入武器装备栏
    }


    //根据名称返回图形
    private GameObject GetPrefabByIconName(string name)
    {
        //获取字典
        //Dictionary<string,GameObject> itemDict = GameObject.FindObjectOfType<GameObject>();

        return null;
    }
}

新增一个标签Image1


在unity中设置背包得第一个格子武器1图片为Image1

修改代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InventoryItemUse : MonoBehaviour
{
    //图标名称
    private string iconName;
    //道具图标点击
    public void OnItemIconClicked() {
        string itemTag = gameObject.tag;
        //图标名称
        //print(gameObject.name);
        iconName = gameObject.name;
        switch (itemTag) {
            case "Image1":
                CanEquipedWeapon();
                break;
        }
    }
    //可被装备的武器
    private void CanEquipedWeapon() {
        //显示在玩家手上
        //print(GetPrefabByIconName(iconName));
        GameObject weapon = GetPrefabByIconName(iconName);
        //定位物体
        Transform weapon1Pos = GameObject.Find("Weapon1_r").transform;
        if (weapon1Pos != null)
        {
            weapon.transform.position = weapon1Pos.position;
            weapon.transform.rotation = weapon1Pos.rotation;
            weapon.transform.SetParent(weapon1Pos);
        }
        //进入武器装备栏
    }


    //根据图标名称    返回模型
    private GameObject GetPrefabByIconName(string name)
    {
        //获取字典
        Dictionary<string, GameObject> itemDict = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerCarryItem>().carryItemDict;
        GameObject prefab = itemDict[name];
        return prefab;
    }
}
复制代码

using UnityEngine;
//可拾取道具
public class CanPickupItem : MonoBehaviour{
    public AudioClip pickUpSound;//拾取声音
    private void OnTriggerEnter(Collider other){
        if (other.CompareTag("Player")){
            //判断绑定脚本的可交互道具是什么
            switch (gameObject.name) {
                case "Weapon1":
                    MoveToItem("Weapon2Pos");
                    break;
                case "Weapon2":
                    MoveToItem("Weapon2Pos");
                    break;
            }
            //播放声音
            if (pickUpSound != null)
                AudioSource.PlayClipAtPoint(pickUpSound, transform.position);
            //将本道具更新到背包列表中
            GameObject.FindGameObjectWithTag("InventoryUITag").
                GetComponent<InventoryManager>().ItemNames.Add(gameObject.name);
            //Destroy(gameObject);
            //将道具模型添加到玩家背包中
            GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerCarryItem>().
                carryItemDict.Add(GetIconNameByItemName(gameObject.name), gameObject);
        }
    }
    //根据道具名称返回图标名称
    private string GetIconNameByItemName(string itemName) {
        string iconName = itemName + "_Icon(Clone)";
        return iconName;
    }

    //转移到玩家身上
    private void MoveToItem(string tagName) {
        //将武器1从地面转移到玩家背上
        //找到武器1在玩家背上的坐标物体
        Transform weapon1Pos = GameObject.FindGameObjectWithTag(tagName).transform;
        //修改步枪的位置及角度,与坐标物体对齐
        transform.position = weapon1Pos.position;
        transform.rotation = weapon1Pos.rotation;
        //将武器2的父物体改为后背的武器2坐标
        transform.SetParent(weapon1Pos);
        //关闭武器2的碰撞器
        gameObject.GetComponent<BoxCollider>().enabled = false;
        //关闭触发器
        gameObject.GetComponent<SphereCollider>().enabled = false;
        //打开忽略物理学运算开关
        gameObject.GetComponent<Rigidbody>().isKinematic = true;
    }
}
即完成运行吃到道具背在身后,在背包中使用道具,背部道具就变成了手里

但是背包中武器不消失

新增一个标签

修改代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InventoryItemUse : MonoBehaviour
{
    //图标名称
    private string iconName;
    //道具图标点击
    public void OnItemIconClicked() {
        string itemTag = gameObject.tag;
        //图标名称
        //print(gameObject.name);
        iconName = gameObject.name;
        switch (itemTag) {
            case "Image1":
                CanEquipedWeapon();
                break;
        }
    }
    //可被装备的武器
    private void CanEquipedWeapon() {
        //显示在玩家手上
        //print(GetPrefabByIconName(iconName));
        GameObject weapon = GetPrefabByIconName(iconName);
        //定位物体
        Transform weapon1Pos = GameObject.Find("Weapon1_r").transform;
        if (weapon1Pos != null)
        {
            weapon.transform.position = weapon1Pos.position;
            weapon.transform.rotation = weapon1Pos.rotation;
            weapon.transform.SetParent(weapon1Pos);
        }
        //进入武器装备栏
        Transform EquipmentBar = GameObject.FindGameObjectWithTag("Image_1").transform;
        transform.SetParent(EquipmentBar);
        RectTransform rt = transform.GetComponent<RectTransform>();
        rt.anchoredPosition = Vector2.zero;
    }


    //根据图标名称    返回模型
    private GameObject GetPrefabByIconName(string name)
    {
        //获取字典
        Dictionary<string, GameObject> itemDict = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerCarryItem>().carryItemDict;
        GameObject prefab = itemDict[name];
        return prefab;
    }
}
运行即可完成使用背包物品后,角色手中显示且背包中物品消失转移到装备栏中

拓展:

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值