当光线投射击中某些东西时,防止在光线投射方向上移动

时间:2018-03-16 06:51:02

标签: c# unity3d

我正在研究第三人称控制器,当玩家面前的光线投射击中某些东西时,我正试图阻止移动。当前播放器与块碰撞时,混合树设置为0,以便显示空闲动画。在这种情况下,玩家似乎没有移动,这显然不是因为它与某些东西发生碰撞,但用户的输入仍然存在。

当玩家按下跳跃按钮时,这是可见的,因为玩家朝着用户最初尝试移动的方向移动。在播放器控制器中,有一部分在跳跃长度期间按下跳跃按钮之后阻止用户移动(直到播放器再次接地)。我正在努力实现的是,当用户移动某物并按下跳跃按钮时,即使没有更多的对撞机,玩家也会跳起并且不会朝着用户最初尝试的方向前进或阻碍。

如果光线投射击中用户将无法在该方向上添加移动的东西,但是仍然能够将玩家转离对象并且只要光线投射没有击中就朝这个方向移动对撞机。

我不是c#向导,所以下面的大部分代码来自教程。我自己可以写一个光线投射,但不知道如何写出我想要实现的其余部分。

编辑:当前脚本

public RaycastHit _Hit;
public LayerMask _RaycastCollidableLayers; //Set this in inspector, makes you able to say which layers should be collided with and which not.
public float _CheckDistance = 5f;

void Update()
    {

        PushStates();

        // Input
        Vector2 input = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
        Vector2 inputDir = input.normalized;
        bool running = Input.GetButton("Run");


        if (IsNotBlocked())
        {
            Move(inputDir, running);
        }

        float animationSpeedPercent = ((running) ? currentSpeed / runSpeed : currentSpeed / walkSpeed * .5f);
        anim.SetFloat("speedPercent", animationSpeedPercent, speedSmoothTime, Time.deltaTime);
        anim.SetFloat("speedPercentPush", animationSpeedPercent, speedSmoothTime, Time.deltaTime);

        // Check if walking or running

        if (animationSpeedPercent < 0.51f)
        {
            if (ShortJumpRaycast())
            {
                if (Input.GetButtonDown("Jump") && Time.time > canJump)
                {
                ShortJump();
                }
            }
            else
            {
                if (Input.GetButtonDown("Jump") && Time.time > canJump)
                {
                    JumpWalk();
                }
            }
        }
        else
        {
            //Debug.Log("You are Running");
            if (Input.GetButtonDown("Jump") && Time.time > canJump)
            {
                JumpRun();
            }
        }

        JumpCheck();
    }

void Move(Vector2 inputDir, bool running)
    {
        if (inputDir != Vector2.zero)
        {
            float targetRotation = Mathf.Atan2(inputDir.x, inputDir.y) * Mathf.Rad2Deg + cameraT.eulerAngles.y;
            transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, targetRotation, ref turnSmoothVelocity, GetModifiedSmoothTime(turnSmoothTime));
        }

        float targetSpeed = ((running) ? runSpeed : walkSpeed) * inputDir.magnitude;
        currentSpeed = Mathf.SmoothDamp(currentSpeed, targetSpeed, ref speedSmoothVelocity, GetModifiedSmoothTime(speedSmoothTime));

        velocityY += Time.deltaTime * gravity;

        Vector3 velocity = transform.forward * currentSpeed + Vector3.up * velocityY;

        controller.Move(velocity * Time.deltaTime);
        currentSpeed = new Vector2(controller.velocity.x, controller.velocity.z).magnitude;

        // Checks if player is not grounded and is falling

        if (GroundCheck())
        {
            velocityY = 0;
            anim.SetBool("onAir", false);
        }
        else
        {
            anim.SetBool("onAir", true);
        }
    }

bool IsNotBlocked()
    {
        Vector3 forward = transform.TransformDirection(Vector3.forward);

        if (Physics.Raycast(transform.position, forward, out _Hit, _CheckDistance + 0.1f, _RaycastCollidableLayers))
            if (_Hit.collider == null)
            {
                Debug.Log("Raycast hit nothing");
                return true;
            }
        GameObject go = _Hit.collider.gameObject;
        if (go == null) //If no object hit, nothing is blocked.
            return true;
        else //An object was hit.
            return false;
    }

2 个答案:

答案 0 :(得分:1)

在移动之前,您可以在移动方向上进行光线投射,如果它碰到某些东西,您可以取消移动。

类似的东西:

Vector3 velocity = transform.forward * currentSpeed + Vector3.up * velocityY;
if(!Physics.Raycast(transform.position, transform.forward, distance)
{
    controller.Move(velocity * Time.deltaTime);
}
else
{
    controller.Move(Vector3.up * velocityY * Time.deltaTime);
}

答案 1 :(得分:1)

  

如果光线投射击中用户赢得的东西并且能够在该方向上添加移动的东西

以下是如何执行光线投射以检查是否有某些内容被击中的示例。

//Example raycast code
//Variables
public RayCastHit _Hit;
public LayerMask _RaycastCollidableLayers; //Set this in inspector, makes you able to say which layers should be collided with and which not.
public float _CheckDistance = 5f;

//Method
bool IsNotBlocked(){
Vector3 forward = transform.TransformDirection(Vector3.forward);

if (Physics.Raycast(transform.position, forward, out _Hit, _CheckDistance + 0.1f, _RaycastCollidableLayers))
if (_Hit.collider == null)
{
    Debug.Log("Raycast hit nothing");
    return true;
}
GameObject go = _Hit.collider.gameObject;
if (go == null) //If no object hit, nothing is blocked.
return true;
else //An object was hit.
return false;
}

基本上,

  • 光线的长度是CheckDistance。

  • RayCastCollidableLayers确定一个对象可以进入的层,以便它可以与我们创建的光线碰撞。

  • 代码设置存储在&#34; forward&#34;中的方向,然后从transform3.Forward方向的transform.position(此脚本附加的对象的位置)执行光线投射。

  • _Hit可以保存所有光线投射命中。然后可以通过它访问对象并将其存储为GameObject。我将此对象称为“去”。

随意提问。