Unity3d Unity 3D:我如何让一个拥有角色控制器的玩家推送另一个拥有角色控制器的玩家?

Unity3d Unity 3D:我如何让一个拥有角色控制器的玩家推送另一个拥有角色控制器的玩家?,unity3d,rigid-bodies,Unity3d,Rigid Bodies,我是unity的新手,我正在学习教程。我正在制作一个脚本,用CharacterController移动一个3D播放器,我附加了另一个脚本,增加了推刚体的功能,但是我如何让播放器推另一个播放器呢?它只是碰撞,但什么也没发生,我不想把它变成刚体 //Script that i use as PlayerController using System.Collections; using System.Collections.Generic; using UnityEngine; public cl

我是unity的新手,我正在学习教程。我正在制作一个脚本,用CharacterController移动一个3D播放器,我附加了另一个脚本,增加了推刚体的功能,但是我如何让播放器推另一个播放器呢?它只是碰撞,但什么也没发生,我不想把它变成刚体

//Script that i use as PlayerController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{

    public float horizontalMove;
    public float verticalMove;
    private Vector3 playerInput;

    public CharacterController player;

    public float playerSpeed;
    public Vector3 movePlayer;
    public float gravity = 9.8f;
    public float fallVelocity;
    public float jumpForce;

    public Camera mainCamera;
    private Vector3 camForward;
    private Vector3 camRight;

    public bool isOnSlope = false;
    private Vector3 hitNormal;
    public float slideVelocity;
    public float slopeForceDown;
    private PushRigidBody pushRigid;
    public float pushPlus;


    // Start is called before the first frame update
    void Start()
    {
        player = GetComponent<CharacterController>();
        //Obtengo el componente Script "PushRigidBody" para poder usar sus metodos y cambiar variables con sus mutadores
        pushRigid = GetComponent<PushRigidBody>();
    }

    // Update is called once per frame
    void Update()
    {
        horizontalMove = Input.GetAxis("Horizontal");
        verticalMove = Input.GetAxis("Vertical");

        playerInput = new Vector3(horizontalMove, 0, verticalMove);
        playerInput = Vector3.ClampMagnitude(playerInput, 1);

        camDirection();

        movePlayer = playerInput.x * camRight + playerInput.z * camForward;

        movePlayer = movePlayer * playerSpeed;

        player.transform.LookAt(player.transform.position + movePlayer);

        SetGravity();


        PlayerSkills();
        player.Move(movePlayer * playerSpeed * Time.deltaTime);


    }
    private void FixedUpdate()
    {

    }

    void camDirection()
    {
        camForward = mainCamera.transform.forward;
        camRight = mainCamera.transform.right;

        camForward.y = 0;
        camRight.y = 0;

        camForward = camForward.normalized;
        camRight = camRight.normalized;
    }

    //Funcion para habilidades de jugador
    public void PlayerSkills()
    {
        if (player.isGrounded && Input.GetButtonDown("Jump"))
        {

            fallVelocity = jumpForce;
            movePlayer.y = fallVelocity;

        }
        //Detecta si presiono la tecla para golpear objeto y aventarlo, si la aprieta aumenta la fuerza con la que golpea, si no, la vuelve a dejar como estaba
        if (Input.GetButton("Fire1"))
        {
            pushRigid.SetPushPower(pushPlus);
        }
        else
        {
            pushRigid.SetPushPower( 0f );
        }

    }

    void SetMov(Vector3 vector)
    {
        movePlayer = movePlayer - vector;
    }

    void SetGravity()
    {

        if (player.isGrounded)
        {
            fallVelocity = -gravity * Time.deltaTime;
            movePlayer.y = fallVelocity;
        }
        else
        {
            fallVelocity -= gravity * Time.deltaTime;
            movePlayer.y = fallVelocity;
        }

        SlideDown();
    }
    //Compara si esta o no en una rampa y aplica fuerzas para deslizar
    public void SlideDown()
    {
        //isOnSlope = angulo >= angulo maximo del charcontroller
        isOnSlope = Vector3.Angle(Vector3.up, hitNormal) >= player.slopeLimit;

        if (isOnSlope)
        {
            movePlayer.x += ((1f - hitNormal.y) * hitNormal.x) * slideVelocity;
            movePlayer.z += ((1f - hitNormal.y) * hitNormal.z) * slideVelocity;

            movePlayer.y += slopeForceDown;

        }

    }

    private void OnControllerColliderHit(ControllerColliderHit hit)
    {
        hitNormal = hit.normal;
    }
}
//我用作PlayerController的脚本
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共类玩家控制器:单行为
{
公众浮动水平移动;
公共浮动垂直移动;
私人矢量3播放器;
公共人物控制器;
公众花车运动员速度;
公共矢量3移动播放器;
公共浮子重力=9.8f;
公众流动速度;
公共安全部队;
公共摄像机;
私人矢量3;
私人矢量3卡姆利特;
公共bool isOnSlope=false;
私人向量3正常;
公共发展;
公众浮标倾斜向下;
私人推刚体推刚体;
公共浮点数;
//在第一帧更新之前调用Start
void Start()
{
player=GetComponent();
//Obtengo el component脚本“PushRigidBody”para poder usar sus metodos y cambiar variables con sus mutadores
pushRigid=GetComponent();
}
//每帧调用一次更新
无效更新()
{
horizontalMove=Input.GetAxis(“水平”);
verticalMove=Input.GetAxis(“垂直”);
playerInput=新矢量3(水平移动、0、垂直移动);
playerInput=Vector3.ClampMagnitude(playerInput,1);
凸轮方向();
movePlayer=playerInput.x*camRight+playerInput.z*camForward;
移动玩家=移动玩家*玩家速度;
player.transform.LookAt(player.transform.position+movePlayer);
设置重力();
运动员技能();
player.Move(movePlayer*playerSpeed*Time.deltaTime);
}
私有void FixedUpdate()
{
}
无效方向()
{
camForward=mainCamera.transform.forward;
camRight=mainCamera.transform.right;
camForward.y=0;
camRight.y=0;
camForward=camForward.normalized;
camRight=camRight.normalized;
}
//jugador哈比利达酒店
公开无效玩家技能()
{
if(player.isground&&Input.GetButtonDown(“跳转”))
{
下降速度=跳跃力;
movePlayer.y=下降速度;
}
//在阿文塔罗大道的高尔夫球场上发现了一种新的技术,一种新的技术,一种新的技术,一种新的技术,一种新的技术
if(Input.GetButton(“Fire1”))
{
pushRigid.SetPushPower(pushPlus);
}
其他的
{
推力刚性。设置推力(0f);
}
}
void SetMov(向量3向量)
{
movePlayer=movePlayer-向量;
}
void SetGravity()
{
如果(player.isGrounded)
{
下降速度=-重力*Time.deltaTime;
movePlayer.y=下降速度;
}
其他的
{
下降速度-=重力*时间增量;
movePlayer.y=下降速度;
}
向下滑动();
}
//这是一个比较好的例子
public void SlideDown()
{
//isOnSlope=angulo>=angulo maximo del charcontroller
isOnSlope=Vector3.Angle(Vector3.up,hitNormal)>=player.slopeLimit;
如果(等坡度)
{
movePlayer.x+=((1f-hitNormal.y)*hitNormal.x)*slideVelocity;
movePlayer.z+=((1f-hitNormal.y)*hitNormal.z)*slideVelocity;
movePlayer.y+=slopeForceDown;
}
}
ControllerColliderHit上的私有无效(ControllerColliderHit命中)
{
hitNormal=hit.normal;
}
}

----------
///我用于推送刚体的脚本
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共类推刚体:单行为
{
公共浮动推力=2.0f;
专用浮点数pushPowerPlus=0f;
ControllerColliderHit上的私有无效(ControllerColliderHit命中)
{
刚体实体=hit.collider.attachedRigidbody;
if(body==null | | body.iskinetic)
{
返回;
}
//这是一个很好的解决方案,没有任何问题
如果(点击移动方向y<-0.8)
{
返回;
}
Vector3 pushDir=新的Vector3(hit.moveDirection.x,0,hit.moveDirection.z);
;
body.velocity=pushDir*(pushPower+pushPowerPlus);
}
public void SetPushPower(float pushPowerVar)
{
pushPowerPlus=pushPowerVar;
}
}

如果您不想使用
刚体
来移动角色,那么如果您也不使用
刚体
来推动角色,并像在更新时使用
主体。移动
一样实现它,这会更容易(这会迫使主体移动每个游戏刻度)

所以你可以给玩家添加一个新的向量,推力,当你碰撞时,你可以设置与你碰撞的另一个玩家的推力向量

然后在更新时,在调用
move
时将推向量添加到移动中,并将其降低到0,以创建去加速的感觉


您可以使用内置的单位线性插值(Lerp)使该“向量平滑地降为零”。

如果您不想使用
刚体
移动角色,如果您也不使用
刚体
进行推送,并像使用
体一样实现它,则更容易(强制身体移动每一个游戏滴答声)

所以你可以给玩家添加一个新的向量,推力,


----------


///Script that i use for push rigidbodys
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PushRigidBody : MonoBehaviour
{

    public float pushPower = 2.0f;
    private float pushPowerPlus = 0f;


    private void OnControllerColliderHit(ControllerColliderHit hit)
    {
        Rigidbody body = hit.collider.attachedRigidbody;


        if (body == null || body.isKinematic)
        {

            return;
        }

        //Si caemos encima de un objeto no queremos empujarlo, se pone encima de el
        if (hit.moveDirection.y < -0.8)
        {
            return;
        }

        Vector3 pushDir = new Vector3(hit.moveDirection.x, 0, hit.moveDirection.z);
        ;

        body.velocity = pushDir * (pushPower + pushPowerPlus);

    }

    public void SetPushPower(float pushPowerVar)
    {
        pushPowerPlus = pushPowerVar;
    }


}