Toán vector là cái vẹo gì?
Cứ nhắc đến vector lại nhớ đến những năm tháng lớp 10 hoàng kim , thời mà đầu những năm cấp 3 lại phải chơi cùng những thứ gọi là vector nhưng chả biết để phải làm gì :)) . Mình khá may mắn vì có người thầy tâm huyết chỉ cho mình từng ứng dụng chi tiết sau mỗi bài học nhưng rồi cũng quên cho đến khi mình bắt đầu làm game thì mới đụng lại vector và hiểu ứng dụng của nó cực kì mạnh mẽ trong làm game nói riêng . Trong ngữ cảnh bài này , mình sẽ giới thiệu sơ qua toán vector và cách ứng dụng toán vector trong làm game cụ thể là unity engine.
1. Toán vector cơ bản
Trong toán học , người ta định nghĩa vector là đại lượng biểu diễn cho hướng và độ lớn . Trong không gian vector được xác định bởi 3 đại lượng x , y ,z
Tương tự , trong unity ta có cấu trúc Vector3 , nó đại diện cho cả Points và Vectors. Một point đại diện cho 1 vị trí nào đó trong không gian trò chơi , còn một Vector đại diện cho hướng và độ lớn
Trong không gian , Đối với một point có tọa độ x ,y ,z là một vị trí duy nhất và đối với một Vector có tọa độ x ,y ,z đại diện cho một độ dài và có vô số vector có độ dài như thế.
2.Tổng - Hiệu Vector và Point
Khi cộng hai vector , ta cộng lần lượt x , y ,z lại với nhau , ví dụ (2,3,5) + (1,3,5) = (3,6,10) . Nó cũng tương tự khi cộng 1 điểm với vector : điểm (2,4,5) + Vector (3,2,2) sẽ trả về kết quả là 1 điểm (5,6,7) , tương tự với phép trừ
Lưu ý :
- Điểm + Vector = Điểm
- Vector + Vector = Vector
Trong game , chúng ta dùng phép cộng và trừ hai vector để di chuyển object xung quanh . Ví dụ ta muốn di chuyển một vật thể từ điểm này đến điểm khác , vector sẽ có tác dụng là chỉ phương và độ lớn đến điểm đó cho ta
Trên tấm ảnh ta có 2 object là zombie và granny . Để zombie có thể di chuyển đến granny và ngược lại buộc ta phải áp dụng phép trừ trong vector . Ví dụ :
Zombie có tọa độ (20,15,20) , Granny có tọa độ (10,15,5)
=> Áp dụng phép trừ hai vector ta có Zombie - Granny = (20,15,20) - (10,15,5) = (10,0,15) là hướng từ Granny đến Zombie(màu hồng) và đương nhiên ta có đường màu xanh = Granny - Zombie
Note : Để lấy hướng từ Point -> Hit , ta lấy Hit - Point
Sau khi lấy được hướng , điều tiếp theo ta chỉ cần zombie di chuyển theo đường màu xanh đến Granny
Lúc này ta sẽ dùng đến sức mạnh của tổng 2 Vector
Ta có 2 Vector A và B khi đó A+B = C như hình vẽ
Như ví dụ trên ta có Vector A là hướng từ world đến vị trí của Zombie(cụ thể là vị trí của zombie) , Vector B đại diện cho hướng ta vừa tính khi nảy(hiệu 2 vector) . Để di chuyển A theo hướng B ta thực hiện : A = A + B*Time.deltatime , cứ như vậy mỗi lần A sẽ di chuyển một đoạn nhỏ theo hướng B
3.Scaling Vectors
Scaling một vector tăng hoặc giảm chỉ tác động đến độ dài của vector nhưng hướng thì không đổi . Cu thể khi nhân một vector cho một số thì rõ ràng cả 2 vector trước và sau đều cùng hướng , cùng phương và cùng vector đơn vị
Trong unity khá đơn giản để scale vector
Vector3 v1 = new Vector3(5,6,7);
Vector3 v2 = v1 * 0.5f;
4 Opposite Vectors
Opposite Vectors mình nhớ nó là vector ngược hướng trong SGK toán lớp 10 , thứ mà khi nhân một vector với một số âm , nó sẽ cho ta một vector ngược hướng với vector ban đầu.
Khi nhân vector đó với -1 . ta nhận được 1 vector ngược hướng nhưng chiều dài không đổi
Trong lập trình game dùng khá nhiều , mình cụ thể 1 trường hợp như trong ảnh
Khi nhân vật của chúng ta một chạy thoát khỏi zombie trong khi đó ta biết hướng của nhân vật đến zombie => nhân vector đó với -1 , ta có hướng ngược lại để chạy đi
Trong mỗi project mình đều dùng opposite vector , nhiều thế nào thì bạn phải tự trải nghiệm :))
5.Distance
Thì như các ví dụ trên , một vector bao gồm hướng và độ dài , độ dài của một vector được gọi là magnitude.
Trong project thực tế , distance dùng nhiều vô số kể , một ví dụ là để tạo AI zombie trong distance bao nhiêu thì có thể di chuyển tấn công
Trong unity độ dài của một vector được tính như sau:
Vector3 v1 = new Vector3(20,35,56);
float length = v1.magnitude;
hoặc
stevie.transform.position = new Vector3(10,15,5);
granny.transform.position = new Vector3(20,15,20);
Vector3 directionToGranny = granny.transform.position - stevie.transform.position
float distanceBetweenStevieGranny = directionToGranny.magnitude;
hoặc dùng hàm Vector3.Distance
6.Angles
Đây là bonus cho phần vector . Để mang lại trải nghiệm tốt nhất , khi di chuyển chúng ta muốn xoay người của nhân vật theo hướng đó . Mình thấy mấy bạn newbie hơi quan trọng hóa vấn đề này nhưng điều này làm không khó và có rất nhiều cách
Để mì ăn liền chúng ta có thể dùng transform.LookAt(pos) , vấn đề xảy ra là nó sẽ quay qua pos ngay lập tức một cách phi vật lý vì vậy để đơn giản hơn ta có :
Vector3 direction = granny.transform.position - stevie.transform.position;
stevie.transform.rotation = Quaternion.Slerp(stevie.transform.rotation,
Quaternion.LookRotation(direction),
Time.deltaTime * rotationSpeed);
Tham số thứ 2 là Quaternion.LookRotation(direction) , trả về một Quaternion khi ta hướng mặt về phía direction.
Còn một cách lúc mới học mình hay xài vì không biết quá nhiều hàm của Unity
alpha = Atan2(direct.z,direct.x) * Mathf.Rad2Deg , nếu là 2d thì đối lại tham số đầu tiên thành direct.y đơn giản vì Atan2 trả về góc alpha hợp bởi direct và trục OX khi tịnh tiến xuống OX , sau đó chuyển sang đơn vị Degree
Cách trên cũng có thể đơn giản hóa bằng :
Vector3 direction = granny.transform.position - stevie.transform.position;
float angleOfRotation = Vector3.Angle(stevie.transform.forward, direction);
Final
Vector phải nói cực kì quan trọng đối với lập trình game , hầu như project nào cũng xài đến vector , vì vậy các bạn nào chưa vững kiến thức thì nhớ ôn lại , thậm chí là mình nhiều lúc cũng khá đù trong việc tính toán trên vector
Cuối cùng , mình hy vọng các bạn hiểu những gì mình truyền đạt trong bài viết này và khá tò mò những gì bạn nghĩ trong bài viết này , nếu bạn có cách để cái tiến điều này tốt hơn , đừng do dự mà hãy comment bên dưới bài viết.
Thanks for reading
cc 123
Trả lờiXóa