Öncelikle bu blog gönderisinin yardımıyla ihtiyaç duyduğum şeyi başardım bulmacanın yüzey yakalama parçası için yazısının ve oyuncu hareketi ve kamera için kendi fikirlerimi buldum.
Oynatıcıyı Nesnenin Yüzeyine Yapıştırma
Temel kurulum, her ikisi de küre çarpıştırıcıları bağlı olan büyük bir küreden (dünya) ve daha küçük bir küreden (oynatıcıdan) oluşur.
Yapılan işin büyük kısmı aşağıdaki iki yöntemdeydi:
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
Beni ilk başta anlamaya yönelik parametre sesler gibi, biz bu örnekte nispeten basit sona erdi ederken, bu çerçevede bizim oyuncu hareketli ve bu vektörü hesaplanması olacak yönü biraz zor oldu. Daha sonra daha fazlası, ancak oyuncunun bu kareyi hareket ettirdiği yönde normalleştirilmiş bir vektör olduğunu unutmayın.
Adım attığımızda, yaptığımız ilk şey, oyunculara vektör (-transform.up) doğru yönlendirilen varsayımsal gelecekteki pozisyondan kaynaklanan bir ışının, komut dosyasının genel LayerMask özelliği olan WorldLayerMask'ı kullanarak dünyaya çarpıp çarpmadığını kontrol etmektir. Daha karmaşık çarpışmalar veya birden fazla katman istiyorsanız, kendi katman maskenizi oluşturmanız gerekir. Raycast bir şeye başarılı bir şekilde vurursa, hitInfo, oynatıcının nesnenin üzerinde olması gereken yeni konumunu ve dönüşünü hesaplamak için normal ve vuruş noktasını almak için kullanılır. Söz konusu oyuncu nesnesinin boyutuna ve kaynağına bağlı olarak, oynatıcının konumunun dengelenmesi gerekebilir.
Son olarak, bu gerçekten sadece test edildi ve muhtemelen sadece küreler gibi basit nesneler üzerinde iyi çalışıyor. Çözümümün önerilerini temel aldığım blog yazısı olarak, daha karmaşık arazilerde hareket ederken çok daha hoş bir geçiş elde etmek için muhtemelen birden fazla rekor kırmak ve konumunuz ve rotasyonunuz için ortalamak isteyeceksiniz. Bu noktada düşünmediğim başka tuzaklar da olabilir.
Kamera ve Hareket
Oyuncu nesnenin yüzeyine yapıştıktan sonra, ele alınması gereken bir sonraki görev hareketti. Başlangıçta oyuncuya göre hareketle başladım ama kürenin direklerinde, yönlerin aniden değiştiği ve oyuncularımın direkleri geçmeme izin vermediği yönünü hızla değiştirdi. Yaptığım şey oyuncularımı kameraya göre hareket ettirmekti.
İhtiyaçlarım için iyi çalışan şey, oyuncuları sadece oyuncuların konumuna göre kesinlikle takip eden bir kameraya sahip olmaktı. Sonuç olarak, kamera teknik olarak dönmesine rağmen, yukarı basmak her zaman oynatıcıyı ekranın üst kısmına, aşağıya doğru ve sola ve sağa doğru hareket ettirdi.
Bunu yapmak için, hedef nesnenin oynatıcı olduğu kamerada aşağıdakiler yürütüldü:
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);
}
Son olarak, oynatıcıyı hareket ettirmek için, ana kameranın dönüşümünü kullandık, böylece kontrollerimiz yukarı hareket ettiğinde, aşağı hareket ettiğinde vb. Ve burada konumumuzu dünya nesnesine yapıştıracak olan UpdatePlayerTransform'u çağırıyoruz.
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);
}
Daha ilginç bir kamera uygulamak için, ancak kontroller burada sahip olduğumuzla hemen hemen aynı olacak şekilde, işlenmemiş bir kamerayı veya hareketi temel almak için sadece başka bir kukla nesneyi kolayca uygulayabilir ve daha sonra Oyunun benzemesini istersiniz. Bu, kontrolleri bozmadan nesnelerin etrafında dolaşırken güzel kamera geçişlerine izin verecektir.