根据相机的方向为球添加力

时间:2016-02-24 05:36:44

标签: c# unity3d game-physics

我正在尝试创建一个迷你高尔夫游戏,但我无法解决如何计算击球的方向。我认为最简单的方法是在相机面向前方的方向上击球,但是在第一次击球后我得到了意想不到的结果,因为在第一次击球后球不会计算出正确的方向。如何设置击球的方向,然后施加我正在计算的力?

这是我目前附在我的球对象上的脚本。抱歉这个混乱。

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class Golfball : MonoBehaviour {
    public GameObject ball = null;
    public GameObject hole = null;
    public GameObject cam = null;
    public Text distance;
    public Text score;
    public Slider powerbar;
    private int strokes = 0;
    private bool isMoving = false;
    private bool increasing = true;
    private float distanceToHole;
    public float minHitPower = 40.0f;
    public float maxHitPower = 270.0f;
    private float hitPower = 0;
    private float powerIncrement = 5.0f;
    private float powerMultiplier = 10;
    private float ballRollTime = 0;
    private Vector3 ballDir;

    // Use this for initialization
    void Start() {
        distance.GetComponent<Text>().text = "Distance To Hole:" + distanceToHole;
        ball.GetComponent<Rigidbody> ();
        score.GetComponent<Text>().text = "Strokes:" + strokes;
    }

    // Update is called once per frame
    void Update () {
        //Allow the ball to be hit if the ball is not null, not currently moving, and the left mouse button is clicked.
        if (ball != null) {

            if (Input.GetButton("Fire1") && !isMoving) {
                calculatePower ();
            }

            //Hit ball using power level and set ball to moving.
            if (Input.GetButtonUp("Fire1"))
            {/**********************************************
                //Calculate direction to hit ball
                ballDir = cam.transform.forward.normalized;
                hitBall(hitPower);
                isMoving = true;
            }**********************************************/

            //Detect when the ball stops
            if (isMoving) {
                ballRollTime += Time.deltaTime;
                if (ballRollTime > 1 && GetComponent<Rigidbody> ().velocity.magnitude <= 0.5) {
                    GetComponent<Rigidbody> ().velocity = Vector3.zero;
                    GetComponent<Rigidbody> ().angularVelocity = Vector3.zero;
                    isMoving = false;
                }
            } else {
                ballRollTime = 0;
            }
        }
        //Calculate distance to hole
        distanceToHole = Mathf.Round((Vector3.Distance(ball.transform.position, hole.transform.position) * 100f) / 100f);
        distance.GetComponent<Text>().text = "Distance To Hole: " + distanceToHole;

        Debug.DrawLine(ball.transform.position, ballDir, Color.red, Mathf.Infinity);
    }

    void calculatePower(){
        //Increase power if it is less than the max power.
        if (increasing)
        {
            if (hitPower < maxHitPower)
            {
                hitPower += powerIncrement * powerMultiplier;
                increasing = true;
            }
            else if (hitPower >= maxHitPower)
            {
                increasing = false;
            }
        }
        //Decrease power if power level is not increasing until the power hits the minimum level.
        if(!increasing) {
            //Debug.Log ("Not Increasing");
            if (hitPower > minHitPower) {
                //Debug.Log ("HitPower: " + hitPower);
                hitPower -= powerIncrement * powerMultiplier;
            } else if (hitPower <= minHitPower) {
                increasing = true;
            }
        }
        //Update the slider
        powerbar.value = hitPower / powerMultiplier;
    }

    void hitBall (float power){

        //Add force to the ball
        //ball.GetComponent<Rigidbody>().AddForce(new Vector3(0, 0, power));
        //Camera.main.transform.forward
        ball.GetComponent<Rigidbody>().AddRelativeForce(ballDir * power);

        //Increase stroke count
        strokes++;
        updateScore(strokes);

        //Reset the power  and power bar level to minimum default after hitting ball
        hitPower = minHitPower;
        powerbar.value = hitPower / powerMultiplier;
        Debug.Log("HitPower Reset: " + hitPower);
    }

    void updateScore(int stroke)
    {
        score.GetComponent<Text>().text = "Strokes:" + stroke;
    }
}

1 个答案:

答案 0 :(得分:0)

你必须像那样使用武力:

ball.GetComponent<Rigidbody>().AddForce(ballDir * power, ForceMode.Impulse);

但你可能不得不玩'power'变量。 还要注意你想要使用冲动,因为你击球并且在一段时间内不施力。

ballDir * power将ballDir向量乘以您的浮点数。你可能已经知道它是如何工作的,但这里是破旧的:

scalarValue * new Vector(x0, x1, ..., xn) == new Vector(scalarValue * x0, scalarValue * x1, ... scalarValue * xn);]

你可能还想摆脱方向的y组件,这样你的球就不会飞到空中(你正在玩迷你高尔夫,对吗?)

ballDir.y = 0;