我试图控制游戏中的对象(例如立方体),并使用由导航网格物体代理控制的第三人称角色与它们一起移动。主要目的是能够在某种程度上抓住立方体(或使立方体与玩家互动时紧贴玩家)并随其移动,最后将立方体放置在卡车后面。当玩家在放置积木时与立方体互动(在卡车后面)时,应出于优化目的而破坏或隐藏该立方体。就像我之前说过的,我的播放器由导航网格物体控制,并具有胶囊和刚性容器,并且我现在有一个交互脚本附加到其他对象上,玩家可以在其中拾取/收集物品,这些物品在我的库存中隐藏并显示插槽。但是与我要实现的目标不同,这些目标是不可动摇的。在此先感谢我希望我能理解(我正在使用Unity 2018.2)。以下是相关代码:
[Code = CSharp]
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(NavMeshAgent))]
public class PlayerMotor : MonoBehaviour
{
Transform target; //Target to follow
NavMeshAgent agent; //Referance to agent
// Use this for initialization
void Start()
{
agent = GetComponent<NavMeshAgent>();
}
void Update()
{
if(target != null)
{
agent.SetDestination(target.position);
FaceTarget();
}
}
public void MoveToPoint(Vector3 point)
{
agent.SetDestination(point);
}
public void FollowTarget(Interactable newTarget)
{
agent.stoppingDistance = newTarget.radius * .8f;
agent.updateRotation = false;
target = newTarget.interactionTransform;
}
public void StopFollowingTarget()
{
agent.stoppingDistance = 0f;
agent.updateRotation = true;
target = null;
}
void FaceTarget()
{
Vector3 direction = (target.position - transform.position).normalized;
Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0f, direction.z));
if(direction != Vector3.zero)
{
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * 5f);
}
}
} [/代码]
[Code = CSharp]
using UnityEngine.EventSystems;
using UnityEngine;
[RequireComponent(typeof(PlayerMotor))]
public class PlayerController : MonoBehaviour
{
Camera cam;
PlayerMotor motor;
public Interactable focus;
public LayerMask movementMask; //Filter out everything not walkable
// Use this for initialization
void Start()
{
cam = Camera.main; //Referance to camera
motor = GetComponent<PlayerMotor>(); //Referance to motor
}
// Update is called once per frame
void Update()
{
if (EventSystem.current.IsPointerOverGameObject())
return;
//If we left click on mouse
if (Input.GetMouseButtonDown(0))
{
//We create a ray
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
//If the ray hits
if (Physics.Raycast(ray, out hit, 100, movementMask))
{
motor.MoveToPoint(hit.point); // Move to where we hit
RemoveFocus();
}
}
//If we right click on mouse
if (Input.GetMouseButtonDown(1))
{
//We create a ray
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
//If the ray hits
if (Physics.Raycast(ray, out hit, 100))
{
Interactable interactable = hit.collider.GetComponent<Interactable>();
if (interactable != null)
{
SetFocus(interactable);
}
}
}
}
void SetFocus(Interactable newFocus)
{
if(newFocus != focus)
{
if(focus != null)
focus.OnDefocused();
focus = newFocus;
motor.FollowTarget(newFocus);
}
newFocus.OnFocused(transform);
}
void RemoveFocus()
{
if(focus != null)
focus.OnDefocused();
focus = null;
motor.StopFollowingTarget();
}
}
[/代码]
[Code = CSharp]
using UnityEngine;
public class Interactable : MonoBehaviour
{
public float radius = 2f;
public Transform interactionTransform;
bool isFocus = false;
Transform player;
bool hasInteracted = false;
public virtual void Interact()
{
//This method is meant to be overwritten
Debug.Log("Interacting with" + transform.name);
}
void Update()
{
if (isFocus && !hasInteracted)
{
float distance = Vector3.Distance(player.position, interactionTransform.position);
if(distance <= radius)
{
Interact();
hasInteracted = true;
}
}
}
public void OnFocused(Transform playerTransform)
{
isFocus = true;
player = playerTransform;
hasInteracted = false;
}
public void OnDefocused()
{
isFocus = false;
player = null;
hasInteracted = false;
}
private void OnDrawGizmosSelected()
{
if (interactionTransform == null)
interactionTransform = transform;
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(interactionTransform.position, radius);
}
}
[/代码]