1、目标
从库存栏中把道具拖到游戏场景中,库存栏中道具数相应做减法或者删除道具。同时在库存栏中可以交换两个道具的位置。
2、UIInventorySlot设置Raycast属性
在UIInventorySlot中,我们只希望最外层的UIInventorySlot响应Raycast,他下面的2个子对象不需要相应Raycast,所以需要取消InventoryHighlight和Text的Raycast Target设置。
3、创建可拖动对象
(1)优化Tags.cs
为了可以方便获取Items对象,新增一个Tag名为ItemsParentTransform,并且将Items标记为ItemsParentTransform。
同时在Assets -> Scripts -> Misc的Tags.cs代码中,新增:
public const string ItemsParentTransform = "ItemsParentTransform";
此时Tags.cs的完整代码是:
using UnityEngine;
public static class Tags
{
public const string BoundsConfiner = "BoundsConfiner";
public const string ItemsParentTransform = "ItemsParentTransform";
}
(2)优化Play.cs
修改Assets -> Scripts -> Player -> Player.cs文件。
当我们用鼠标拖动道具到场景中时,我们不希望角色跟着鼠标移动。
改动1:将已有逻辑移到判断PlayerInputIsDisabled下,当输入不被禁用时才移动。
private void Update()
{
#region Player Input
if (!PlayerInputIsDisabled)
{
ResetAnimationTrigger();
PlayerMovementInput();
PlayerWalkInput();
// Send event to any listeners for player movement input
EventHandler.CallMovementEvent(xInput, yInput, isWalking, isRunning, isIdle, isCarrying, toolEffect,
isUsingToolRight, isUsingToolLeft, isUsingToolUp, isUsingToolDown,
isLiftingToolRight, isLiftingToolLeft, isLiftingToolUp, isLiftingToolDown,
isPickingRight, isPickingLeft, isPickingUp, isPickingDown,
isSwingToolRight, isSwingToolLeft, isSwingToolUp, isSwingToolDown,
false, false, false, false);
}
#endregion Player Input
}
改动2:创建禁用/启动输入的函数
public void DisablePlayerInpupt()
{
PlayerInputIsDisabled = true;
}
public void EnablePlayerInput()
{
PlayerInputIsDisabled = false;
}
改动3:对外提供的函数,禁用输入,并且设置用户为静止状态。
public void DisablePlayerInputAndResetMovement()
{
DisablePlayerInpupt();
ResetMovement();
// Send event to any listeners for player movement input
EventHandler.CallMovementEvent(xInput, yInput, isWalking, isRunning, isIdle, isCarrying, toolEffect,
isUsingToolRight, isUsingToolLeft, isUsingToolUp, isUsingToolDown,
isLiftingToolRight, isLiftingToolLeft, isLiftingToolUp, isLiftingToolDown,
isPickingRight, isPickingLeft, isPickingUp, isPickingDown,
isSwingToolRight, isSwingToolLeft, isSwingToolUp, isSwingToolDown,
false, false, false, false);
}
private void ResetMovement()
{
// Reset movement
xInput = 0f;
yInput = 0f;
isRunning = false;
isWalking = false;
isIdle = true;
}
Player.cs完整的代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : SingletonMonobehaviour<Player>
{
private float xInput;
private float yInput;
private bool isWalking;
private bool isRunning;
private bool isIdle;
private bool isCarrying = false;
private ToolEffect toolEffect = ToolEffect.none;
private bool isUsingToolRight;
private bool isUsingToolLeft;
private bool isUsingToolUp;
private bool isUsingToolDown;
private bool isLiftingToolRight;
private bool isLiftingToolLeft;
private bool isLiftingToolUp;
private bool isLiftingToolDown;
private bool isPickingRight;
private bool isPickingLeft;
private bool isPickingUp;
private bool isPickingDown;
private bool isSwingToolRight;
private bool isSwingToolLeft;
private bool isSwingToolUp;
private bool isSwingToolDown;
private Camera mainCamera;
private Rigidbody2D rigidbody2D;
private Direction playerDirection;
private float movementSpeed;
private bool _playerInputIsDisabled = false;
public bool PlayerInputIsDisabled { get => _playerInputIsDisabled; set => _playerInputIsDisabled = value; }
protected override void Awake()
{
base.Awake();
rigidbody2D = GetComponent<Rigidbody2D>();
mainCamera = Camera.main;
}
private void Update()
{
#region Player Input
if (!PlayerInputIsDisabled)
{
ResetAnimationTrigger();
PlayerMovementInput();
PlayerWalkInput();
// Send event to any listeners for player movement input
EventHandler.CallMovementEvent(xInput, yInput, isWalking, isRunning, isIdle, isCarrying, toolEffect,
isUsingToolRight, isUsingToolLeft, isUsingToolUp, isUsingToolDown,
isLiftingToolRight, isLiftingToolLeft, isLiftingToolUp, isLiftingToolDown,
isPickingRight, isPickingLeft, isPickingUp, isPickingDown,
isSwingToolRight, isSwingToolLeft, isSwingToolUp, isSwingToolDown,
false, false, false, false);
}
#endregion Player Input
}
private void FixedUpdate()
{
PlayerMovement();
}
private void PlayerMovement()
{
Vector2 move = new Vector2(xInput * movementSpeed * Time.deltaTime, yInput * movementSpeed * Time.deltaTime);
rigidbody2D.MovePosition(rigidbody2D.position + move);
}
private void ResetAnimationTrigger()
{
toolEffect = ToolEffect.none;
isUsingToolRight = false;
isUsingToolLeft = false;
isUsingToolUp = false;
isUsingToolDown = false;
isLiftingToolRight = false;
isLiftingToolLeft = false;
isLiftingToolUp = false;
isLiftingToolDown = false;
isPickingRight = false;
isPickingLeft = false;
isPickingUp = false;
isPickingDown = false;
isSwingToolRight = false;
isSwingToolLeft = false;
isSwingToolUp = false;
isSwingToolDown = false;
}
private void PlayerMovementInput()
{
xInput = Input.GetAxisRaw("Horizontal");
yInput = Input.GetAxisRaw("Vertical");
// 斜着移动
if (xInput != 0 && yInput != 0)
{
xInput = xInput * 0.71f;
yInput = yInput * 0.71f;
}
// 在移动
if (xInput != 0 || yInput != 0)
{
isRunning = true;
isWalking = false;
isIdle = false;
movementSpeed = Settings.runningSpeed;
// Capture player direction for save game
if (xInput < 0)
{
playerDirection = Direction.left;
}
else if (xInput > 0)
{
playerDirection = Direction.right;
}
else if (yInput < 0)
{
playerDirection = Direction.down;
}
else
{
playerDirection = Direction.up;
}
}
else if(xInput == 0 && yInput == 0)
{
isRunning = false;
isWalking = false;
isIdle = true;
}
}
// 按住Shift键移动为walk
private void PlayerWalkInput()
{
if(Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
{
isRunning = false;
isWalking = true;
isIdle = false;
movementSpeed = Settings.walkingSpeed;
}
else
{
isRunning = true;
isWalking = false;
isIdle = false;
movementSpeed = Settings.runningSpeed;
}
}
public Vector3 GetPlayerViewportPosition()
{
// Vector3 viewport position for player (0,0) viewport bottom left, (1,1) viewport top right
return mainCam