Вопрос достаточно интересный, потому как решения я найти не могу уже долго. В чем суть:
У меня есть игрок на котором висит CharacterController и собственно скрипт который им управляет. В иерархии под игроком камера, под камерой рука (пустой объект) а к ней крепится объект который я беру. Проблема в том, что объекты которые я беру проходят сквозь любые другие объекты(игрок их проталкивает). Думаю дело в том что игрок является нефизическим, в отличии от предмета.
Я хочу сделать так, чтобы коллайдер предмета который я беру становился как бы продолжение коллайдера игрока, чтобы если я подойду к стене с объектом то игрок просто уперся в него.
Вот скрипты:
PlayerMovement:
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public static PlayerMovement Instance;
public GameObject player;
public footstep footstepScript;
public CharacterController controller;
public float speed = 12f;
public float speed_walking;
public float speed_sprinting = 6f;
public float speed_crouching = 2f;
public float walkingDelay;
public float sprintingDelay;
public float gravity = -9.81f;
public float jumpHeight = 3f;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
private float velocityNew;
private Vector3 previous;
private Vector3 velocity;
public bool isGrounded;
public bool playerIsNowMoving;
public bool playerSprinting;
public bool footstepsEnabled;
public bool jumpingEnabled;
public bool sprintingEnabled;
public AudioSource streetSound;
public bool isPlayerStopped = false;
private Vector3 lastVelocity;
private Vector3 lastInput;
public MouseLook mouseLook;
public DisableInput disableInput;
void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
private void Start()
{
footstepsEnabled = true;
streetSound.Play();
}
private void Update()
{
if (isPlayerStopped)
return;
velocityNew = (transform.position - previous).magnitude / Time.deltaTime;
previous = transform.position;
if (sprintingEnabled)
{
if (Input.GetKey(KeyCode.LeftShift))
{
playerSprinting = true;
speed = speed_sprinting;
footstepScript.footstepDelay = sprintingDelay;
}
if (Input.GetKeyUp(KeyCode.LeftShift))
{
playerSprinting = false;
speed = speed_walking;
footstepScript.footstepDelay = walkingDelay;
}
}
if (jumpingEnabled && Input.GetButtonDown("Jump") && isGrounded)
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
isGrounded = Physics.Raycast(groundCheck.position, Vector3.down, groundDistance + 0.1f, groundMask);
if (isGrounded && velocity.y < 0f)
{
velocity.y = -2f;
}
else
{
velocity.y += gravity * Time.deltaTime;
}
playerIsNowMoving = velocityNew > 0.1;
float axis = Input.GetAxis("Horizontal");
float axis2 = Input.GetAxis("Vertical");
Vector3 inputDirection = new Vector3(axis, 0f, axis2).normalized;
Vector3 moveDirection = transform.right * axis + transform.forward * axis2;
moveDirection = Vector3.ClampMagnitude(moveDirection, 1f);
controller.Move(moveDirection * speed * Time.deltaTime);
controller.Move(velocity * Time.deltaTime);
}
public void StopPlayer()
{
if (isPlayerStopped)
return;
disableInput.inputDisabled = true;
isPlayerStopped = true;
lastVelocity = velocity;
velocity = Vector3.zero;
lastInput = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
if (footstepScript != null)
{
footstepScript.footstepsEnabled = false;
}
if (mouseLook != null)
{
mouseLook.playerCanLookAround = false;
}
}
public void ResumePlayer()
{
if (!isPlayerStopped)
return;
disableInput.inputDisabled = false;
isPlayerStopped = false;
velocity = lastVelocity;
if (footstepScript != null)
{
footstepScript.footstepsEnabled = true;
}
if (mouseLook != null)
{
mouseLook.playerCanLookAround = true;
}
}
}
PickingItems:
using UnityEngine;
public class PickingItems : MonoBehaviour
{
[Header("Raycast Settings")]
public Camera cam;
public float range = 2f;
public LayerMask ignoreMask;
[Header("Other Settings")]
public Transform handObj;
private GameObject heldItem;
private Rigidbody heldItemRb;
[SerializeField] private float pickupForce = 50f;
void Update()
{
if (Input.GetKeyDown(KeyManager.instance.keyInput))
{
if (heldItem == null)
{
TryPickUp();
}
else
{
DropItem();
}
}
if (heldItem != null)
{
MoveObject();
}
}
void MoveObject()
{
if (Vector3.Distance(heldItem.transform.position, handObj.position) > 0.1f)
{
Vector3 moveDirection = (handObj.position - heldItem.transform.position);
heldItemRb.AddForce(moveDirection * pickupForce);
}
}
void TryPickUp()
{
if (Physics.Raycast(cam.transform.position, cam.transform.forward, out RaycastHit hit, range, ~ignoreMask))
{
if (hit.collider.CompareTag("Klad") || hit.collider.CompareTag("OilLamp"))
{
PickUp(hit.collider.gameObject);
}
}
}
void PickUp(GameObject item)
{
heldItem = item;
heldItemRb = heldItem.GetComponent<Rigidbody>();
heldItemRb.useGravity = false;
heldItem.transform.SetParent(handObj);
heldItemRb.drag = 5;
heldItemRb.constraints = RigidbodyConstraints.FreezeRotation;
heldItem.transform.localPosition = Vector3.zero;
heldItem.transform.localRotation = Quaternion.identity;
}
void DropItem()
{
if (heldItem)
{
heldItem.transform.SetParent(null);
heldItemRb.useGravity = true;
heldItemRb.drag = 1;
heldItemRb.constraints = RigidbodyConstraints.None;
heldItem = null;
heldItemRb = null;
}
}
}