Tôi đã xoay sở để hoàn thành những gì tôi cần, chủ yếu là với sự hỗ trợ của bài đăng trên blog này cho mảnh ghép bề mặt của câu đố và đưa ra ý tưởng của riêng tôi cho chuyển động của người chơi và máy ảnh.
Đưa người chơi lên bề mặt của một vật thể
Thiết lập cơ bản bao gồm một quả cầu lớn (thế giới) và một quả cầu nhỏ hơn (người chơi) cả với các máy va chạm hình cầu gắn liền với chúng.
Phần lớn công việc đang được thực hiện là theo hai phương pháp sau:
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;
}
Các Vector3 movementDirection
thông số chỉ là như âm thanh, hướng chúng ta sẽ được di chuyển máy nghe nhạc của chúng tôi trong khung này, và tính toán vector rằng, trong khi kết thúc tương đối đơn giản trong ví dụ này, là một chút khó khăn cho tôi để tìm ra lúc đầu. Nhiều hơn về điều đó sau, nhưng hãy nhớ rằng đó là một vectơ chuẩn hóa theo hướng người chơi đang di chuyển khung này.
Bước qua, điều đầu tiên chúng ta làm là kiểm tra xem một tia, xuất phát từ vị trí tương lai giả định hướng về phía người chơi vectơ (-transform.up) tấn công thế giới bằng WorldLayerMask, một thuộc tính LayerMask công khai của tập lệnh. Nếu bạn muốn va chạm phức tạp hơn hoặc nhiều lớp, bạn sẽ phải xây dựng mặt nạ lớp của riêng mình. Nếu raycast tấn công thành công thứ gì đó, hitInfo sẽ được sử dụng để lấy điểm bình thường và điểm nhấn để tính toán vị trí và góc quay mới của trình phát cần ở ngay trên đối tượng. Bù đắp vị trí của người chơi có thể được yêu cầu tùy thuộc vào kích thước và nguồn gốc của đối tượng người chơi được đề cập.
Cuối cùng, điều này thực sự chỉ được thử nghiệm và có khả năng chỉ hoạt động tốt trên các đối tượng đơn giản như hình cầu. Khi bài đăng trên blog tôi dựa trên giải pháp của tôi gợi ý, bạn có thể muốn thực hiện nhiều chương trình phát sóng và lấy trung bình chúng cho vị trí và xoay của mình để có được sự chuyển tiếp đẹp hơn khi di chuyển trên địa hình phức tạp hơn. Cũng có thể có những cạm bẫy khác mà tôi không nghĩ đến vào thời điểm này.
Máy ảnh và chuyển động
Khi người chơi đã bám vào bề mặt của vật thể, nhiệm vụ tiếp theo cần giải quyết là chuyển động. Ban đầu tôi đã bắt đầu với chuyển động liên quan đến người chơi nhưng tôi bắt đầu gặp vấn đề ở các cực của quả cầu nơi các hướng đột nhiên thay đổi khiến người chơi của tôi nhanh chóng thay đổi hướng đi và không cho phép tôi vượt qua các cực. Những gì tôi cố gắng làm là làm cho các cầu thủ của tôi chuyển động liên quan đến máy ảnh.
Điều làm việc tốt cho nhu cầu của tôi là có một chiếc máy ảnh tuân thủ nghiêm ngặt người chơi chỉ dựa trên vị trí người chơi. Kết quả là, mặc dù máy ảnh đã quay kỹ thuật, nhấn lên luôn di chuyển người chơi về phía trên màn hình, xuống phía dưới, và cứ thế với trái và phải.
Để thực hiện việc này, các thao tác sau được thực hiện trên máy ảnh có đối tượng mục tiêu là trình phát:
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);
}
Cuối cùng, để di chuyển trình phát, chúng tôi đã tận dụng sự biến đổi của camera chính để với các điều khiển của chúng tôi di chuyển lên, di chuyển xuống, v.v. Và ở đây chúng tôi gọi là UpdatePlayerTransform sẽ đưa vị trí của chúng tôi vào vị trí của thế giới.
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);
}
Để thực hiện một máy ảnh thú vị hơn nhưng các điều khiển giống như những gì chúng tôi có ở đây, bạn có thể dễ dàng thực hiện một máy ảnh không được kết xuất hoặc chỉ là một đối tượng giả khác để di chuyển khỏi cơ sở và sau đó sử dụng máy ảnh thú vị hơn để hiển thị những gì bạn muốn trò chơi trông như thế nào Điều này sẽ cho phép chuyển đổi camera đẹp khi bạn đi xung quanh các đối tượng mà không phá vỡ các điều khiển.