2016-02-24 24 views
0

我試圖製作迷你高爾夫球比賽,但在解決如何計算擊球方向時遇到了問題。我認爲在相機朝前的方向上擊球是最容易的,但是在第一次擊球后我會得到意想不到的結果,因爲在第一次擊球后球不會計算正確的方向。我如何設定擊球方向,然後應用我正在計算的力量?根據攝像機的方向給球添加力

這是我的腳本附加到我的球對象的時刻。對不起,混亂。

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; 
    } 
} 

回答

0

你必須施加力這樣的:

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

但你可能會與你的「權力」變量以播放。 另外請注意,你想使用衝動,因爲你擊球並且在一段時間內不施加力量。

ballDir * power以您的浮點數乘以ballDir向量。你可能已經知道它是如何工作的,但這裏的破敗:

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

你可能也想擺脫方向的y組件,使你的球並沒有飛入空氣(你在玩迷你高爾夫球場,右?)

ballDir.y = 0; 
+0

OP:Mokona提到了什麼,(我看到你評論了部分代碼)確保ballDir設置爲相機的正向。如果你問我,我會直接在強制分配中使用相機的矢量,因爲ballDir可能會在其他地方意外更改。 – andeart

+0

我其實已經找到了問題所在。當我擊球時,我的球對象的x和z軸與對象一起旋轉,因此當我第一次擊球時,球變換的旋轉值爲0,0,0。擊球后,這些旋轉值將球定向得很多不同的,所以球會根據Z軸指向的新方向撞向相機。我禁用旋轉來解決問題,現在一切按預期工作。我可以添加圖像以顯示我以後的意思。 – user3786596