উত্তরটি আসলে গণিতটি করা খুব সহজ। আপনার Y এর একটি নির্দিষ্ট দূরত্ব এবং এক্সের পরিবর্তনশীল দূরত্ব রয়েছে (চিত্র 1 দেখুন)। আপনাকে জেড এবং এক্স এর মধ্যবর্তী কোণটি খুঁজে বের করতে হবে এবং আপনার বারানাকে আরও অনেক বেশি ঘোরানো হবে।
পদক্ষেপ 1 - বদ্ধ লাইন (ভি) এবং বন্দুকের লাইন (ডাব্লু) এর মধ্যে দূরত্ব পান যা ওয়াই (এটি ধ্রুবক তবে গণনায় আঘাত দেয় না)। টারেট থেকে লক্ষ্য পর্যন্ত দূরত্ব পান (যা এক্স)।
পদক্ষেপ 2 - এক্স দ্বারা Y কে ভাগ করুন এবং তারপরে মানটির হাইপারবোলিক সাইন পান
double turnRadians = Mathf.Asin(Y/X);
double angle = Mathf.Rad2Deg * turnRadians;
//where B is the red dot, A is a point on the X line and C is a point on the Z line.
পদক্ষেপ 3 - আরও অনেক বেশি বারটিকে ঘুরিয়ে দিন (অক্ষের চারপাশে এটি শীর্ষ থেকে নীচে চলে যায়, সম্ভবত অক্ষটি আপ হয় তবে কেবল আপনি সেই অংশটি জানতে পারবেন)।
gameObject.transform.Rotate(Vector3.up, turnAngle);
অবশ্যই এক্ষেত্রে আপনার এটিকে ঘড়ির কাঁটার বিপরীতে ঘুরিয়ে দেওয়ার প্রয়োজন হয় যাতে আপনি সেখানে যেমন বাঁকটি আঙ্গুলের সামনে একটি বিয়োগ যোগ করতে পারেন -turnAngle
।
কিছু অংশ সম্পাদনা করেছেন। দূরত্বের পার্থক্যটি নির্দেশ করার জন্য @ জেনসকে ধন্যবাদ।
ওপি জানিয়েছে যে তার বন্দুকটির একটি কোণ রয়েছে তাই আমরা এখানে যাই, চিত্রটি আগে, পরে ব্যাখ্যা:
আমরা আগের গণনা থেকে ইতিমধ্যে জানি যেখানে নীল রেখা অনুযায়ী লাল রেখাকে লক্ষ্য করা যায়। তাই প্রথমে নীল রেখার লক্ষ্যে:
float turnAngle = angleBetweenTurretAndTarget - angleBetweenTurretAndGun;
turret.transform.Rotate(Vector3.up, turnAngle);
এখানে কেবলমাত্র গণনাটি পৃথক হয়েছে, "এক্স প্রাইম" (এক্স ') এর গণনা কারণ বন্দুক এবং বুড়ি (কোণ "ক") এর মধ্যবর্তী কোণটি রেখার মধ্যবর্তী দূরত্বকে পরিবর্তন করেছিল।
//(this part had a mistake of using previous code inside new variable names, YPrime and Y are shown as X' and X in the 2nd picture.
float YPrime = Cos(a)*Y; //this part is what @ens is doing in his answer
double turnRadians = Mathf.Asin(YPrime/X);
double angle = Mathf.Rad2Deg * turnRadians;
turret.transform.Rotate(Vector3.up, angle);
এই বার্টটি কেবলমাত্র প্রয়োজনীয় যদি আপনি বদ্ধ বন্দুকগুলি মডিউলার করে থাকেন (অর্থাত্ ব্যবহারকারী একটি বুরুজে বন্দুক পরিবর্তন করতে পারে এবং বিভিন্ন বন্দুকের আলাদা আলাদা কোণ থাকে)। আপনি যদি এডিটরটিতে এটি করছেন, আপনি ইতিমধ্যে দেখতে পাবেন বন্দুক অনুসারে বন্দুকের কোণটি কী।
"ক" কোণটি আবিষ্কার করার জন্য দুটি পদ্ধতি রয়েছে, একটি হ'ল ট্রান্সফর্ম.আপ পদ্ধতি:
float angleBetween = Vector3.Angle(turret.transform.up, gun.transform.up);
উপরের কৌশলটি 3 ডি তে গণনা করবে, সুতরাং আপনি যদি 2 ডি ফলাফল চান তবে আপনাকে জেড অক্ষ থেকে মুক্তি দিতে হবে (এটি আমি গ্রাভিটি যেখানে ধরে নিয়েছি তা অনুমান করে তবে আপনি যদি কিছুই পরিবর্তন করেন না, ইউনিটিতে এটি Y অক্ষ, যা উপরে বা নীচে রয়েছে, অর্থাত্ মাধ্যাকর্ষণটি Y অক্ষরেখার উপর রয়েছে, সুতরাং আপনাকে জিনিসগুলি পরিবর্তন করতে হতে পারে):
Vector2 turretVector = new Vector2(turret.transform.up.x, turret.transform.up.y);
Vector2 gunVector = new Vector2(gun.transform.up.x, gun.transform.up.y);
float angleBetween = Vector2.Angle(turretVector, gunVector);
দ্বিতীয় উপায় হ'ল ঘূর্ণন পদ্ধতি (আমি এই ক্ষেত্রে 2 ডি তে ভাবছি):
double angleRadians = Mathf.Asin(turret.transform.rotation.z - gun.transform.rotation.z);
double angle = 2 * Mathf.Rad2Deg * angleRadians;
আবার, এই সমস্ত কোডগুলি আপনাকে ধনাত্মক মান দেয়, সুতরাং আপনাকে কোণের উপর নির্ভর করে পরিমাণ যুক্ত করতে বা বিয়োগ করতে হতে পারে (তার জন্য গণনাও রয়েছে, তবে আমি সেই গভীরতার দিকে যাব না)। এটি শুরু করার জন্য একটি ভাল জায়গাটি হবে Vector2.Dot
ইউনিটির পদ্ধতি।
আমরা কী করছি তার অতিরিক্ত ব্যাখ্যার জন্য কোডের চূড়ান্ত অবরুদ্ধ:
//turn turret towards target
turretTransform.up = targetTransform.position - turretTransform.position;
//adjust for gun angle
if (weaponTransform.localEulerAngles.z <180) //if the value is over 180 it's actually a negative for us
turretTransform.Rotate(Vector3.forward, 90 - b - a);
else
turretTransform.Rotate(Vector3.forward, 90 - b + a);
যদি আপনি সবকিছু ঠিকঠাক করেন তবে আপনার মতো একটি দৃশ্য পাওয়া উচিত ( unityক্যপ্যাকেজের জন্য লিঙ্ক ):
আমি সর্বদা ইতিবাচক মানগুলির দ্বারা যা বোঝাতে চাইছি:
জেড পদ্ধতিটি নেতিবাচক মান দিতে পারে:
উদাহরণস্বরূপ দৃশ্যের জন্য, এই লিঙ্কটি থেকে unityক্যপ্যাকেজ পান ।
আমি দৃশ্যে (টিউটারে) কোডটি ব্যবহার করেছি:
public class TurretAimCorrection : MonoBehaviour
{
public Transform targetTransform;
public Transform turretTransform;
public Transform weaponTransform;
private float f, d, x, y, h, b, a, weaponAngle, turnAngle;
private void Start()
{
TurnCorrection();
}
private void Update()
{
TurnCorrection();
}
void TurnCorrection()
{
//find distances and angles
d = Vector2.Distance(new Vector2(targetTransform.position.x, targetTransform.position.y), new Vector2(turretTransform.position.x, turretTransform.position.y));
x = Vector2.Distance(new Vector2(turretTransform.position.x, turretTransform.position.y), new Vector2(weaponTransform.position.x, weaponTransform.position.y));
weaponAngle = weaponTransform.localEulerAngles.z;
weaponAngle = weaponAngle * Mathf.Deg2Rad;
y = Mathf.Abs(Mathf.Cos(weaponAngle) * x);
b = Mathf.Rad2Deg * Mathf.Acos(y / d);
a = Mathf.Rad2Deg * Mathf.Acos(y / x);
//turn turret towards target
turretTransform.up = targetTransform.position - turretTransform.position;
//adjust for gun angle
if (weaponTransform.localEulerAngles.z < 180)
turretTransform.Rotate(Vector3.forward, 90 - b - a);
else
turretTransform.Rotate(Vector3.forward, 90 - b + a);
//Please leave this comment in the code. This code was made by
//http://gamedev.stackexchange.com/users/93538/john-hamilton a.k.a. CrazyIvanTR.
//This code is provided as is, with no guarantees. It has worked in local tests on Unity 5.5.0f3.
}
}
2 ডি প্লেন হিসাবে X এবং Z এর সাথে 3D অভিযোজিত কোড:
public class TurretAimCorrection : MonoBehaviour
{
public Transform targetTransform; //drag target here
public Transform turretTransform; //drag turret base or turret top part here
public Transform weaponTransform; //drag the attached weapon here
private float d, x, y, b, a, weaponAngle, turnAngle;
private void Start()
{
TurnAdjustment();
}
private void Update()
{
TurnAdjustment();
}
void TurnAdjustment()
{
d = Vector2.Distance(new Vector2(targetTransform.position.x, targetTransform.position.z), new Vector2(turretTransform.position.x, turretTransform.position.z));
x = Vector2.Distance(new Vector2(turretTransform.position.x, turretTransform.position.z), new Vector2(weaponTransform.position.x, weaponTransform.position.z));
weaponAngle = weaponTransform.localEulerAngles.y;
weaponAngle = weaponAngle * Mathf.Deg2Rad;
y = Mathf.Abs(Mathf.Cos(weaponAngle) * x);
b = Mathf.Rad2Deg * Mathf.Acos(y / d);
a = Mathf.Rad2Deg * Mathf.Acos(y / x);
//turn turret towards target
turretTransform.forward = new Vector3(targetTransform.position.x, 0, targetTransform.position.z) - new Vector3(turretTransform.position.x, 0, turretTransform.position.z);
//adjust for gun angle
if (weaponTransform.localEulerAngles.y < 180)
turretTransform.Rotate(Vector3.up, - a +b-90);
else
turretTransform.Rotate(Vector3.up, + a+ b - 90);
//Please leave this comment in the code. This code was made by
//http://gamedev.stackexchange.com/users/93538/john-hamilton a.k.a. CrazyIvanTR.
//This code is provided as is, with no guarantees. It has worked in local tests on Unity 5.5.0f3.
}
}