• unity2d 完美斜坡方案


    来自油管大神:https://www.youtube.com/watch?v=QPiZSTEuZnw&lc=z22ehdxp5wmrg1jkvacdp431qmalafpquvm0apfrjrxw03c010c&feature=em-comments

    核心代码

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class PlayerController : MonoBehaviour
    {
    
        [SerializeField]
        private float movementSpeed;
        [SerializeField]
        private float groundCheckRadius;
        [SerializeField]
        private float jumpForce;
        [SerializeField]
        private float slopeCheckDistance;
        [SerializeField]
        private float maxSlopeAngle;
        [SerializeField]
        private Transform groundCheck;
        [SerializeField]
        private LayerMask whatIsGround;
        [SerializeField]
        private PhysicsMaterial2D noFriction;
        [SerializeField]
        private PhysicsMaterial2D fullFriction;
    
        private float xInput;
        private float slopeDownAngle;
        private float slopeSideAngle;
        private float lastSlopeAngle;
    
        private int facingDirection = 1;
    
        private bool isGrounded;
        private bool isOnSlope;
        private bool isJumping;
        private bool canWalkOnSlope;
        private bool canJump;
    
        private Vector2 newVelocity;
        private Vector2 newForce;
        private Vector2 capsuleColliderSize;
    
        private Vector2 slopeNormalPerp;
    
        private Rigidbody2D rb;
        private CapsuleCollider2D cc;
    
        private void Start()
        {
            rb = GetComponent<Rigidbody2D>();
            cc = GetComponent<CapsuleCollider2D>();
    
            capsuleColliderSize = cc.size;
        }
    
        private void Update()
        {
            CheckInput();     
        }
    
        private void FixedUpdate()
        {
            CheckGround();
            SlopeCheck();
            ApplyMovement();
        }
    
        private void CheckInput()
        {
            xInput = Input.GetAxisRaw("Horizontal");
    
            if (xInput == 1 && facingDirection == -1)
            {
                Flip();
            }
            else if (xInput == -1 && facingDirection == 1)
            {
                Flip();
            }
    
            if (Input.GetButtonDown("Jump"))
            {
                Jump();
            }
    
        }
        private void CheckGround()
        {
            isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround);
    
            if(rb.velocity.y <= 0.0f)
            {
                isJumping = false;
            }
    
            if(isGrounded && !isJumping && slopeDownAngle <= maxSlopeAngle)
            {
                canJump = true;
            }
    
        }
    
        private void SlopeCheck()
        {
            Vector2 checkPos = transform.position - (Vector3)(new Vector2(0.0f, capsuleColliderSize.y / 2));
    
            SlopeCheckHorizontal(checkPos);
            SlopeCheckVertical(checkPos);
        }
    
        private void SlopeCheckHorizontal(Vector2 checkPos)
        {
            RaycastHit2D slopeHitFront = Physics2D.Raycast(checkPos, transform.right, slopeCheckDistance, whatIsGround);
            RaycastHit2D slopeHitBack = Physics2D.Raycast(checkPos, -transform.right, slopeCheckDistance, whatIsGround);
    
            if (slopeHitFront)
            {
                isOnSlope = true;
    
                slopeSideAngle = Vector2.Angle(slopeHitFront.normal, Vector2.up);
    
            }
            else if (slopeHitBack)
            {
                isOnSlope = true;
    
                slopeSideAngle = Vector2.Angle(slopeHitBack.normal, Vector2.up);
            }
            else
            {
                slopeSideAngle = 0.0f;
                isOnSlope = false;
            }
    
        }
    
        private void SlopeCheckVertical(Vector2 checkPos)
        {      
            RaycastHit2D hit = Physics2D.Raycast(checkPos, Vector2.down, slopeCheckDistance, whatIsGround);
    
            if (hit)
            {
    
                slopeNormalPerp = Vector2.Perpendicular(hit.normal).normalized;            
    
                slopeDownAngle = Vector2.Angle(hit.normal, Vector2.up);
    
                if(slopeDownAngle != lastSlopeAngle)
                {
                    isOnSlope = true;
                }                       
    
                lastSlopeAngle = slopeDownAngle;
               
                Debug.DrawRay(hit.point, slopeNormalPerp, Color.blue);
                Debug.DrawRay(hit.point, hit.normal, Color.green);
    
            }
    
            if (slopeDownAngle > maxSlopeAngle || slopeSideAngle > maxSlopeAngle)
            {
                canWalkOnSlope = false;
            }
            else
            {
                canWalkOnSlope = true;
            }
    
            if (isOnSlope && canWalkOnSlope && xInput == 0.0f)
            {
                rb.sharedMaterial = fullFriction;
            }
            else
            {
                rb.sharedMaterial = noFriction;
            }
        }
    
        private void Jump()
        {
            if (canJump)
            {
                canJump = false;
                isJumping = true;
                newVelocity.Set(0.0f, 0.0f);
                rb.velocity = newVelocity;
                newForce.Set(0.0f, jumpForce);
                rb.AddForce(newForce, ForceMode2D.Impulse);
            }
        }   
    
        private void ApplyMovement()
        {
            if (isGrounded && !isOnSlope && !isJumping) //if not on slope
            {
                Debug.Log("This one");
                newVelocity.Set(movementSpeed * xInput, 0.0f);
                rb.velocity = newVelocity;
            }
            else if (isGrounded && isOnSlope && canWalkOnSlope && !isJumping) //If on slope
            {
                newVelocity.Set(movementSpeed * slopeNormalPerp.x * -xInput, movementSpeed * slopeNormalPerp.y * -xInput);
                rb.velocity = newVelocity;
            }
            else if (!isGrounded) //If in air
            {
                newVelocity.Set(movementSpeed * xInput, rb.velocity.y);
                rb.velocity = newVelocity;
            }
    
        }
    
        private void Flip()
        {
            facingDirection *= -1;
            transform.Rotate(0.0f, 180.0f, 0.0f);
        }
    
        private void OnDrawGizmos()
        {
            Gizmos.DrawWireSphere(groundCheck.position, groundCheckRadius);
        }
    
    }

    工程地址:https://drive.google.com/drive/folders/1qxFq3EBkU0JLu_iwXOtEc9-dW6_C1SpL

  • 相关阅读:
    机器学习中的概念和名词解释
    NLPIR文本智能分词是语义挖掘的关键
    学习NLPIR语义智能教学科研平台要这样打开
    NLPIR语义智能:大数据与人才成行业发展瓶颈
    NLPIR:大数据挖掘技术引导数据应用
    2018大数据新动态:NLPIR语义智能教学科研平台
    灵玖软件:大数据语言新特征发现
    JZSearch大数据智能搜索网络数据
    大数据信息挖掘中文分词是关键
    灵玖软件:NLPIR文本智能挖掘提速2.0
  • 原文地址:https://www.cnblogs.com/sanyejun/p/12577525.html
Copyright © 2020-2023  润新知