كاميرا الشخص الثالث في Unity
A كاميرا الشخص الثالث هي نوع من الكاميرات يتم وضعها خلف اللاعب، وعادةً ما يتم إزاحتها قليلاً إلى الجانب، مما يوفر تمثيلاً مرئيًا لمستوى اللعبة واللاعب نفسه.
لإنشاء كاميرا تصويب من منظور شخص ثالث (TPS) في Unity، سنستخدم مزيجًا من حركة اللاعب العادية وعرض منظور الشخص الثالث.
الخطوة 1: إنشاء وحدة تحكم المشغل
أولاً، سنقوم بإنشاء وحدة تحكم اللاعب التي ستتولى التدوير والحركة:
- قم بإنشاء كائن لعبة جديد (كائن اللعبة -> إنشاء فارغ) وقم بتسميته "Player"
- قم بإنشاء كبسولة جديدة (كائن اللعبة -> كائن ثلاثي الأبعاد -> كبسولة) وحركها داخل الكائن "Player"
- قم بإزالة مكون مصادم الكبسولة من الكبسولة وقم بتغيير موضعه إلى (0، 1، 0)
- قم بإنشاء كائن GameObject جديد وقم بتسميته "CameraParent" وانقله داخل الكائن "Player"، وقم بتغيير موضعه إلى (0, 1.64, 0)
- حرك الكاميرا الرئيسية داخل الكائن "CameraParent" وحركها خلف المشغل (في حالتي قمت بنقلها إلى هذا الموضع: (0.5، 0.6، -2.9))
- قم بإنشاء سكريبت جديد، وأطلق عليه اسم SC_TPSController، والصق الكود أدناه بداخله:
SC_TPSController.cs
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class SC_TPSController : MonoBehaviour
{
public float speed = 7.5f;
public float jumpSpeed = 8.0f;
public float gravity = 20.0f;
public Transform playerCameraParent;
public float lookSpeed = 2.0f;
public float lookXLimit = 60.0f;
CharacterController characterController;
Vector3 moveDirection = Vector3.zero;
Vector2 rotation = Vector2.zero;
[HideInInspector]
public bool canMove = true;
void Start()
{
characterController = GetComponent<CharacterController>();
rotation.y = transform.eulerAngles.y;
}
void Update()
{
if (characterController.isGrounded)
{
// We are grounded, so recalculate move direction based on axes
Vector3 forward = transform.TransformDirection(Vector3.forward);
Vector3 right = transform.TransformDirection(Vector3.right);
float curSpeedX = canMove ? speed * Input.GetAxis("Vertical") : 0;
float curSpeedY = canMove ? speed * Input.GetAxis("Horizontal") : 0;
moveDirection = (forward * curSpeedX) + (right * curSpeedY);
if (Input.GetButton("Jump") && canMove)
{
moveDirection.y = jumpSpeed;
}
}
// Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below
// when the moveDirection is multiplied by deltaTime). This is because gravity should be applied
// as an acceleration (ms^-2)
moveDirection.y -= gravity * Time.deltaTime;
// Move the controller
characterController.Move(moveDirection * Time.deltaTime);
// Player and Camera rotation
if (canMove)
{
rotation.y += Input.GetAxis("Mouse X") * lookSpeed;
rotation.x += -Input.GetAxis("Mouse Y") * lookSpeed;
rotation.x = Mathf.Clamp(rotation.x, -lookXLimit, lookXLimit);
playerCameraParent.localRotation = Quaternion.Euler(rotation.x, 0, 0);
transform.eulerAngles = new Vector2(0, rotation.y);
}
}
}
- قم بإرفاق البرنامج النصي SC_TPSController بالكائن "Player" (ستلاحظ أنه أضاف أيضًا مكونًا آخر يسمى Character Controller. قم بتغيير قيمته المركزية إلى (0، 1، 0))
- قم بتعيين الكائن "CameraParent" للمتغير "Player Camera Parent"
الخطوة 2: إضافة كشف تصادم الكاميرا
سيتكون اكتشاف تصادم الكاميرا من برنامج نصي يتحقق مما إذا كان هناك أي شيء بين الكاميرا والمشغل، وسيقوم تلقائيًا بتقريب الكاميرا، وبالتالي يمنع الكاميرا من قطع الكائنات.
- قم بإنشاء برنامج نصي جديد، وقم بتسميته SC_CameraCollision ثم الصق الكود أدناه بداخله:
SC_CameraCollision.cs
using UnityEngine;
public class SC_CameraCollision : MonoBehaviour
{
public Transform referenceTransform;
public float collisionOffset = 0.3f; //To prevent Camera from clipping through Objects
public float cameraSpeed = 15f; //How fast the Camera should snap into position if there are no obstacles
Vector3 defaultPos;
Vector3 directionNormalized;
Transform parentTransform;
float defaultDistance;
// Start is called before the first frame update
void Start()
{
defaultPos = transform.localPosition;
directionNormalized = defaultPos.normalized;
parentTransform = transform.parent;
defaultDistance = Vector3.Distance(defaultPos, Vector3.zero);
//Lock cursor
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
// LateUpdate is called after Update
void LateUpdate()
{
Vector3 currentPos = defaultPos;
RaycastHit hit;
Vector3 dirTmp = parentTransform.TransformPoint(defaultPos) - referenceTransform.position;
if (Physics.SphereCast(referenceTransform.position, collisionOffset, dirTmp, out hit, defaultDistance))
{
currentPos = (directionNormalized * (hit.distance - collisionOffset));
transform.localPosition = currentPos;
}
else
{
transform.localPosition = Vector3.Lerp(transform.localPosition, currentPos, Time.deltaTime * cameraSpeed);
}
}
}
- قم بإرفاق البرنامج النصي SC_CameraCollision بالكاميرا الرئيسية
- قم بتعيين الكائن "CameraParent" للمتغير "Reference Transform"
- قم بتعديل قيم "Collision Offset" و"Camera Speed" في حالة قيام الكاميرا بالقص عبر الجدران
كاميرا TPS جاهزة الآن، اضغط على تشغيل لاختبارها.