Задать вопрос
mckruasan
@mckruasan
Junior Python, Html, CSS

Как избежать прохождения объектов в руке сквозь другие объекты (коллайдеры)?

Вопрос достаточно интересный, потому как решения я найти не могу уже долго. В чем суть:
У меня есть игрок на котором висит 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;
        }
    }
}
  • Вопрос задан
  • 10 просмотров
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы