ฉันจัดการเพื่อให้บรรลุสิ่งที่ฉันต้องการเป็นหลักด้วยความช่วยเหลือของโพสต์บล็อกนี้สำหรับชิ้นส่วนของปริศนาและเกิดขึ้นกับความคิดของฉันสำหรับการเคลื่อนไหวของผู้เล่นและกล้อง
Snapping Player กับพื้นผิวของวัตถุ
การตั้งค่าพื้นฐานประกอบด้วยทรงกลมขนาดใหญ่ (โลก) และทรงกลมขนาดเล็ก (ผู้เล่น) ทั้งคู่ที่มี colliders ทรงกลมติดอยู่
งานที่ทำเสร็จแล้วมีสองวิธีดังต่อไปนี้:
private void UpdatePlayerTransform(Vector3 movementDirection)
{
RaycastHit hitInfo;
if (GetRaycastDownAtNewPosition(movementDirection, out hitInfo))
{
Quaternion targetRotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
Quaternion finalRotation = Quaternion.RotateTowards(transform.rotation, targetRotation, float.PositiveInfinity);
transform.rotation = finalRotation;
transform.position = hitInfo.point + hitInfo.normal * .5f;
}
}
private bool GetRaycastDownAtNewPosition(Vector3 movementDirection, out RaycastHit hitInfo)
{
Vector3 newPosition = transform.position;
Ray ray = new Ray(transform.position + movementDirection * Speed, -transform.up);
if (Physics.Raycast(ray, out hitInfo, float.PositiveInfinity, WorldLayerMask))
{
return true;
}
return false;
}
Vector3 movementDirection
พารามิเตอร์เป็นเพียงเสียงทิศทางที่เราจะได้รับการเคลื่อนย้ายผู้เล่นของเราในกรอบนี้และการคำนวณเวกเตอร์ว่าในขณะที่จบลงด้วยการที่ค่อนข้างง่ายในตัวอย่างนี้เป็นบิตหากินสำหรับผมที่จะคิดออกในตอนแรก เพิ่มเติมในภายหลัง แต่โปรดจำไว้ว่ามันเป็นเวกเตอร์ที่ทำให้เป็นมาตรฐานในทิศทางที่ผู้เล่นเคลื่อนไหวเฟรมนี้
สิ่งแรกที่เราทำคือตรวจสอบว่ามีรังสีเกิดขึ้นที่ตำแหน่งสมมุติในอนาคตที่มุ่งไปยังผู้เล่นแบบเวกเตอร์ (-transform.up) กระทบโลกโดยใช้ WorldLayerMask ซึ่งเป็นคุณสมบัติ LayerMask สาธารณะของสคริปต์ หากคุณต้องการการชนที่ซับซ้อนมากขึ้นหรือหลายเลเยอร์คุณจะต้องสร้างเลเยอร์มาสก์ของคุณเอง หาก raycast พบสิ่งที่ hitInfo ประสบความสำเร็จจะใช้ในการดึงจุดปกติและจุด Hit เพื่อคำนวณตำแหน่งใหม่และการหมุนของผู้เล่นซึ่งควรจะอยู่บนวัตถุ การชดเชยตำแหน่งของผู้เล่นอาจจำเป็นขึ้นอยู่กับขนาดและที่มาของวัตถุผู้เล่นที่มีปัญหา
ในที่สุดสิ่งนี้ได้รับการทดสอบจริง ๆ เท่านั้นและน่าจะใช้ได้กับวัตถุง่าย ๆ เช่นทรงกลมเท่านั้น ในขณะที่โพสต์บล็อกที่ฉันใช้วิธีแก้ปัญหาของฉันออกจากการแนะนำคุณอาจต้องการดำเนินการหลาย raycasts และค่าเฉลี่ยพวกเขาสำหรับตำแหน่งและการหมุนของคุณเพื่อรับการเปลี่ยนแปลงที่ดีกว่ามากเมื่อย้ายภูมิประเทศที่ซับซ้อนมากขึ้น อาจมีข้อผิดพลาดอื่น ๆ ที่ฉันไม่เคยคิดมาก่อนในตอนนี้
กล้องและการเคลื่อนไหว
เมื่อผู้เล่นติดกับพื้นผิวของวัตถุภารกิจต่อไปที่จะแก้ไขก็คือการเคลื่อนไหว ตอนแรกฉันเริ่มต้นด้วยการเคลื่อนไหวที่สัมพันธ์กับผู้เล่น แต่ฉันเริ่มพบปัญหาที่เสาของทรงกลมซึ่งทิศทางเปลี่ยนไปอย่างกะทันหันทำให้ผู้เล่นของฉันเปลี่ยนทิศทางไปเรื่อย ๆ อย่างรวดเร็วไม่ให้ฉันผ่านเสา สิ่งที่ฉันทำคือการทำให้ผู้เล่นเคลื่อนไหวสัมพันธ์กับกล้อง
สิ่งที่ทำงานได้ดีสำหรับความต้องการของฉันคือการมีกล้องที่ติดตามผู้เล่นอย่างเคร่งครัดตามตำแหน่งของผู้เล่นเท่านั้น แม้ว่ากล้องจะหมุนในทางเทคนิคการกดขึ้นจะเลื่อนผู้เล่นไปทางด้านบนของหน้าจอลงไปทางด้านล่างและไปทางซ้ายและขวา
เมื่อต้องการทำสิ่งนี้จะมีการดำเนินการต่อไปนี้กับกล้องที่มีวัตถุเป้าหมายคือเครื่องเล่น:
private void FixedUpdate()
{
// Calculate and set camera position
Vector3 desiredPosition = this.target.TransformPoint(0, this.height, -this.distance);
this.transform.position = Vector3.Lerp(this.transform.position, desiredPosition, Time.deltaTime * this.damping);
// Calculate and set camera rotation
Quaternion desiredRotation = Quaternion.LookRotation(this.target.position - this.transform.position, this.target.up);
this.transform.rotation = Quaternion.Slerp(this.transform.rotation, desiredRotation, Time.deltaTime * this.rotationDamping);
}
ในที่สุดเมื่อต้องการย้ายผู้เล่นเราใช้ประโยชน์จากการแปลงของกล้องหลักเพื่อให้มีการควบคุมของเราเลื่อนขึ้นลงย้ายลง ฯลฯ และที่นี่เราเรียก UpdatePlayerTransform ซึ่งจะได้ตำแหน่งของเรา snapped กับวัตถุโลก
void Update ()
{
Vector3 movementDirection = Vector3.zero;
if (Input.GetAxisRaw("Vertical") > 0)
{
movementDirection += cameraTransform.up;
}
else if (Input.GetAxisRaw("Vertical") < 0)
{
movementDirection += -cameraTransform.up;
}
if (Input.GetAxisRaw("Horizontal") > 0)
{
movementDirection += cameraTransform.right;
}
else if (Input.GetAxisRaw("Horizontal") < 0)
{
movementDirection += -cameraTransform.right;
}
movementDirection.Normalize();
UpdatePlayerTransform(movementDirection);
}
ในการใช้กล้องที่น่าสนใจยิ่งขึ้น แต่การควบคุมให้ใกล้เคียงกับสิ่งที่เรามีในที่นี้คุณสามารถใช้กล้องที่ไม่ได้แสดงผลหรือวัตถุจำลองอื่น ๆ เพื่อสร้างการเคลื่อนไหวจากนั้นใช้กล้องที่น่าสนใจเพื่อแสดงว่า คุณต้องการให้เกมดูเป็นอย่างไร สิ่งนี้จะช่วยให้การเปลี่ยนกล้องดีในขณะที่คุณเดินไปรอบ ๆ วัตถุโดยไม่ทำลายการควบคุม