コード例 #1
0
    void OnInteractionTriggerEnter(ChildCollider callingChildCollider, Collider other)
    {
        BaseInteraction interactable = other.gameObject.GetComponent <BaseInteraction>();

        if (interactable)
        {
            overlappingInteractables.Add(other);
            if (overlappingInteractables.Count < 2)
            {
                selectedInteractable = interactable;
                selectedInteractable.OnSelected();
            }
        }

        return;
    }
コード例 #2
0
    // Update is called once per frame
    void Update()
    {
        // Cache local variables
        Vector3 movementAcceleration = Vector3.zero;
        float   deltaTime            = Time.deltaTime;
        bool    moveAxisPressed      = PlayerInputManager.PlayerActions.moveAxis.IsPressed && CanWalk();

        // Update lateral movement if appropriate
        if (moveAxisPressed || ownerCharacterController.velocity.sqrMagnitude > 0.0f)
        {
            // Transform camera space input into world space
            // If movement is pressed use the pressed direction
            // Otherwise, use the current velocity
            Vector3 horizontalDirection;
            float   horizontalAccelerationScalar = 1.0f;
            if (moveAxisPressed)
            {
                Vector2 moveInput = new Vector2(PlayerInputManager.PlayerActions.moveAxis.X, PlayerInputManager.PlayerActions.moveAxis.Y);
                horizontalDirection          = ownerCamera.transform.TransformDirection(new Vector3(moveInput.x, 0.0f, moveInput.y));
                horizontalDirection.y        = 0.0f;
                horizontalAccelerationScalar = Mathf.Clamp(moveInput.magnitude, -1.0f, 1.0f);
            }
            else
            {
                horizontalDirection = new Vector3(ownerCharacterController.velocity.x, 0.0f, ownerCharacterController.velocity.z);
            }

            if (horizontalDirection != Vector3.zero)
            {
                // Normalize to get the final movement direction
                horizontalDirection.Normalize();

                // Get the acceleration based on the movement direction
                movementAcceleration = GetHorizontalAcceleration(horizontalDirection, horizontalAccelerationScalar, deltaTime);

                // Rotate towards the movement direction
                transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(horizontalDirection), movementTurningSpeed * deltaTime);
            }

            characterAnimator.SetBool(walkAnimKey, true);
        }
        else
        {
            characterAnimator.SetBool(walkAnimKey, false);
        }

        // Update jump state
        if (ownerCharacterController.isGrounded)
        {
            // Start when pressed
            if (PlayerInputManager.PlayerActions.jump.WasPressed && CanJump())
            {
                verticalSpeed      = jumpAcceleration;
                fatJumping         = true;
                jumpStartTimeStamp = Time.time;
                characterAnimator.SetBool(jumpAnimKey, true);
            }
            // Stop when on the ground
            else
            {
                verticalSpeed = -gravity;
                fatJumping    = false;
                characterAnimator.SetBool(jumpAnimKey, false);
            }
        }

        // Update falling state
        else
        {
            // Update fat jumping
            if (fatJumping)
            {
                // End fat jump when jump released or we go beyond the maximum time
                if (!PlayerInputManager.PlayerActions.jump.IsPressed || Time.time - jumpStartTimeStamp > fatJumpTime)
                {
                    fatJumping     = false;
                    verticalSpeed -= gravity * Time.deltaTime;
                }

                // Otherwise, continue fat jumping
                // Do nothing in that case
            }

            // Handle gradual deceleration
            else
            {
                // Double deceleration at jump maximum
                verticalSpeed -= gravity * deltaTime * (verticalSpeed < 0.0f ? 2.0f : 1.0f);
            }
        }

        // Combine and apply horizontal and vertical movement
        movementAcceleration.y = verticalSpeed * deltaTime;
        if (movementAcceleration != Vector3.zero)
        {
            ownerCharacterController.Move(movementAcceleration);
        }

        // Update the best interactable if appropriate
        if (overlappingInteractables.Count > 1)
        {
            // Find the interactable we are closest to
            BaseInteraction bestInteractable = null;
            float           smallestDistance = 9999.0f;
            foreach (Collider interactable in overlappingInteractables)
            {
                float distanceToInteractable = Vector3.Distance(ownerCharacterController.transform.position, interactable.transform.position);
                if (distanceToInteractable < smallestDistance)
                {
                    bestInteractable = interactable.gameObject.GetComponent <BaseInteraction>();
                    smallestDistance = distanceToInteractable;
                }
            }

            // Update our best interactable
            if (bestInteractable != selectedInteractable)
            {
                // Deselect old best
                if (selectedInteractable)
                {
                    selectedInteractable.OnDeselected();
                }

                // Select new best
                selectedInteractable = bestInteractable;
                if (selectedInteractable)
                {
                    selectedInteractable.OnSelected();
                }
            }
        }

        // Interact with selected interactable if appropriate
        if (PlayerInputManager.PlayerActions.interact.WasPressed && selectedInteractable && CanInteract())
        {
            selectedInteractable.TryInteract();
            for (int i = 0; i < overlappingInteractables.Count; i++)
            {
                if (selectedInteractable.gameObject.name == overlappingInteractables[i].gameObject.name)
                {
                    EnableDisable overlap = overlappingInteractables[i].GetComponent <EnableDisable>();
                    for (int x = 0; x < overlap.toDisable.Length; x++)
                    {
                        if (overlap.toDisable[x].gameObject.name == selectedInteractable.gameObject.name)
                        {
                            overlappingInteractables.RemoveAt(i);
                        }
                    }
                }
            }
        }
    }