mirror of
https://github.com/godotengine/godot-docs.git
synced 2025-12-31 17:49:03 +03:00
Fix a few more links + add missing attachment
This commit is contained in:
145
files/resource_queue.gd
Normal file
145
files/resource_queue.gd
Normal file
@@ -0,0 +1,145 @@
|
||||
var thread
|
||||
var mutex
|
||||
var sem
|
||||
|
||||
var time_max = 100 # msec
|
||||
|
||||
var queue = []
|
||||
var pending = {}
|
||||
|
||||
func _lock(caller):
|
||||
mutex.lock()
|
||||
|
||||
func _unlock(caller):
|
||||
mutex.unlock()
|
||||
|
||||
func _post(caller):
|
||||
sem.post()
|
||||
|
||||
func _wait(caller):
|
||||
sem.wait()
|
||||
|
||||
|
||||
func queue_resource(path, p_in_front = false):
|
||||
_lock("queue_resource")
|
||||
if path in pending:
|
||||
_unlock("queue_resource")
|
||||
return
|
||||
|
||||
elif ResourceLoader.has(path):
|
||||
var res = ResourceLoader.load(path)
|
||||
pending[path] = res
|
||||
_unlock("queue_resource")
|
||||
return
|
||||
else:
|
||||
var res = ResourceLoader.load_interactive(path)
|
||||
res.set_meta("path", path)
|
||||
if p_in_front:
|
||||
queue.insert(0, res)
|
||||
else:
|
||||
queue.push_back(res)
|
||||
pending[path] = res
|
||||
_post("queue_resource")
|
||||
_unlock("queue_resource")
|
||||
return
|
||||
|
||||
func cancel_resource(path):
|
||||
_lock("cancel_resource")
|
||||
if path in pending:
|
||||
if pending[path] extends ResourceInteractiveLoader:
|
||||
queue.erase(pending[path])
|
||||
pending.erase(path)
|
||||
_unlock("cancel_resource")
|
||||
|
||||
func get_progress(path):
|
||||
_lock("get_progress")
|
||||
var ret = -1
|
||||
if path in pending:
|
||||
if pending[path] extends ResourceInteractiveLoader:
|
||||
ret = float(pending[path].get_stage()) / float(pending[path].get_stage_count())
|
||||
else:
|
||||
ret = 1.0
|
||||
_unlock("get_progress")
|
||||
|
||||
return ret
|
||||
|
||||
func is_ready(path):
|
||||
var ret
|
||||
_lock("is_ready")
|
||||
if path in pending:
|
||||
ret = !(pending[path] extends ResourceInteractiveLoader)
|
||||
else:
|
||||
ret = false
|
||||
|
||||
_unlock("is_ready")
|
||||
|
||||
return ret
|
||||
|
||||
func _wait_for_resource(res, path):
|
||||
_unlock("wait_for_resource")
|
||||
while true:
|
||||
VS.flush()
|
||||
OS.delay_usec(16000) # wait 1 frame
|
||||
_lock("wait_for_resource")
|
||||
if queue.size() == 0 || queue[0] != res:
|
||||
return pending[path]
|
||||
_unlock("wait_for_resource")
|
||||
|
||||
|
||||
func get_resource(path):
|
||||
_lock("get_resource")
|
||||
if path in pending:
|
||||
if pending[path] extends ResourceInteractiveLoader:
|
||||
var res = pending[path]
|
||||
if res != queue[0]:
|
||||
var pos = queue.find(res)
|
||||
queue.remove(pos)
|
||||
queue.insert(0, res)
|
||||
|
||||
res = _wait_for_resource(res, path)
|
||||
|
||||
pending.erase(path)
|
||||
_unlock("return")
|
||||
return res
|
||||
|
||||
else:
|
||||
var res = pending[path]
|
||||
pending.erase(path)
|
||||
_unlock("return")
|
||||
return res
|
||||
else:
|
||||
_unlock("return")
|
||||
return ResourceLoader.load(path)
|
||||
|
||||
func thread_process():
|
||||
_wait("thread_process")
|
||||
|
||||
_lock("process")
|
||||
|
||||
while queue.size() > 0:
|
||||
|
||||
var res = queue[0]
|
||||
|
||||
_unlock("process_poll")
|
||||
var ret = res.poll()
|
||||
_lock("process_check_queue")
|
||||
|
||||
if ret == ERR_FILE_EOF || ret != OK:
|
||||
var path = res.get_meta("path")
|
||||
if path in pending: # else it was already retrieved
|
||||
pending[res.get_meta("path")] = res.get_resource()
|
||||
|
||||
queue.erase(res) # something might have been put at the front of the queue while we polled, so use erase instead of remove
|
||||
|
||||
_unlock("process")
|
||||
|
||||
|
||||
func thread_func(u):
|
||||
while true:
|
||||
thread_process()
|
||||
|
||||
func start():
|
||||
mutex = Mutex.new()
|
||||
sem = Semaphore.new()
|
||||
thread = Thread.new()
|
||||
thread.start(self, "thread_func", 0)
|
||||
@@ -34,7 +34,7 @@ directly to wchar_t.
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/typedefs.h <https://github.com/okamstudio/godot/blob/master/core/typedefs.h>`__
|
||||
- `core/typedefs.h <https://github.com/godotengine/godot/blob/master/core/typedefs.h>`__
|
||||
|
||||
Memory model
|
||||
------------
|
||||
@@ -132,8 +132,8 @@ locked until they go out of scope.
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/os/memory.h <https://github.com/okamstudio/godot/blob/master/core/os/memory.h>`__
|
||||
- `core/dvector.h <https://github.com/okamstudio/godot/blob/master/core/dvector.h>`__
|
||||
- `core/os/memory.h <https://github.com/godotengine/godot/blob/master/core/os/memory.h>`__
|
||||
- `core/dvector.h <https://github.com/godotengine/godot/blob/master/core/dvector.h>`__
|
||||
|
||||
Containers
|
||||
----------
|
||||
@@ -166,10 +166,10 @@ The Vector<> class also has a few nice features:
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/vector.h <https://github.com/okamstudio/godot/blob/master/core/vector.h>`__
|
||||
- `core/list.h <https://github.com/okamstudio/godot/blob/master/core/list.h>`__
|
||||
- `core/set.h <https://github.com/okamstudio/godot/blob/master/core/set.h>`__
|
||||
- `core/map.h <https://github.com/okamstudio/godot/blob/master/core/map.h>`__
|
||||
- `core/vector.h <https://github.com/godotengine/godot/blob/master/core/vector.h>`__
|
||||
- `core/list.h <https://github.com/godotengine/godot/blob/master/core/list.h>`__
|
||||
- `core/set.h <https://github.com/godotengine/godot/blob/master/core/set.h>`__
|
||||
- `core/map.h <https://github.com/godotengine/godot/blob/master/core/map.h>`__
|
||||
|
||||
String
|
||||
------
|
||||
@@ -182,7 +182,7 @@ conversion and visualization.
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/ustring.h <https://github.com/okamstudio/godot/blob/master/core/ustring.h>`__
|
||||
- `core/ustring.h <https://github.com/godotengine/godot/blob/master/core/ustring.h>`__
|
||||
|
||||
StringName
|
||||
----------
|
||||
@@ -198,7 +198,7 @@ is fast.
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/string_db.h <https://github.com/okamstudio/godot/blob/master/core/string_db.h>`__
|
||||
- `core/string_db.h <https://github.com/godotengine/godot/blob/master/core/string_db.h>`__
|
||||
|
||||
Math types
|
||||
----------
|
||||
@@ -209,7 +209,7 @@ directory, they are basically just that.
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/math <https://github.com/okamstudio/godot/blob/master/core/math>`__
|
||||
- `core/math <https://github.com/godotengine/godot/blob/master/core/math>`__
|
||||
|
||||
NodePath
|
||||
--------
|
||||
@@ -220,7 +220,7 @@ referencing them fast.
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/path_db.h <https://github.com/okamstudio/godot/blob/master/core/path_db.h>`__
|
||||
- `core/path_db.h <https://github.com/godotengine/godot/blob/master/core/path_db.h>`__
|
||||
|
||||
RID
|
||||
---
|
||||
@@ -233,4 +233,4 @@ referenced data.
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/rid.h <https://github.com/okamstudio/godot/blob/master/core/rid.h>`__
|
||||
- `core/rid.h <https://github.com/godotengine/godot/blob/master/core/rid.h>`__
|
||||
|
||||
@@ -216,7 +216,7 @@ the project folder inside the module directory and configure it:
|
||||
As of this writing, godot uses minsdk 10 and target sdk 15. If this ever
|
||||
changes, should be reflected in the manifest template:
|
||||
|
||||
https://github.com/okamstudio/godot/blob/master/platform/android/AndroidManifest.xml.template
|
||||
https://github.com/godotengine/godot/blob/master/platform/android/AndroidManifest.xml.template
|
||||
|
||||
Then, add the module folder to the project:
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ This makes objects gain a lot of functionality, like for example
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/object.h <https://github.com/okamstudio/godot/blob/master/core/object.h>`__
|
||||
- `core/object.h <https://github.com/godotengine/godot/blob/master/core/object.h>`__
|
||||
|
||||
Registering an Object
|
||||
---------------------
|
||||
@@ -85,7 +85,7 @@ string passing the name can be passed for brevity.
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/object_type_db.h <https://github.com/okamstudio/godot/blob/master/core/object_type_db.h>`__
|
||||
- `core/object_type_db.h <https://github.com/godotengine/godot/blob/master/core/object_type_db.h>`__
|
||||
|
||||
Constants
|
||||
---------
|
||||
@@ -248,7 +248,7 @@ templates point to it.
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/reference.h <https://github.com/okamstudio/godot/blob/master/core/reference.h>`__
|
||||
- `core/reference.h <https://github.com/godotengine/godot/blob/master/core/reference.h>`__
|
||||
|
||||
Resources:
|
||||
----------
|
||||
@@ -264,7 +264,7 @@ Resources without a path are fine too.
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/resource.h <https://github.com/okamstudio/godot/blob/master/core/resource.h>`__
|
||||
- `core/resource.h <https://github.com/godotengine/godot/blob/master/core/resource.h>`__
|
||||
|
||||
Resource loading
|
||||
----------------
|
||||
@@ -285,7 +285,7 @@ the same time.
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/io/resource_loader.h <https://github.com/okamstudio/godot/blob/master/core/io/resource_loader.h>`__
|
||||
- `core/io/resource_loader.h <https://github.com/godotengine/godot/blob/master/core/io/resource_loader.h>`__
|
||||
|
||||
Resource saving
|
||||
---------------
|
||||
@@ -304,4 +304,4 @@ be bundled with the saved resource and assigned sub-IDs, like
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/io/resource_saver.h <https://github.com/okamstudio/godot/blob/master/core/io/resource_saver.h>`__
|
||||
- `core/io/resource_saver.h <https://github.com/godotengine/godot/blob/master/core/io/resource_saver.h>`__
|
||||
|
||||
@@ -37,7 +37,7 @@ of c++ with little effort. Become a friend of Variant today.
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/variant.h <https://github.com/godotengine/okamstudio/godot/blob/master/core/variant.h>`__
|
||||
- `core/variant.h <https://github.com/godotengine/godotengine/godot/blob/master/core/variant.h>`__
|
||||
|
||||
Dictionary and Array
|
||||
--------------------
|
||||
@@ -58,5 +58,5 @@ desired.
|
||||
References:
|
||||
~~~~~~~~~~~
|
||||
|
||||
- `core/dictionary.h <https://github.com/okamstudio/godot/blob/master/core/dictionary.h>`__
|
||||
- `core/array.h <https://github.com/okamstudio/godot/blob/master/core/array.h>`__
|
||||
- `core/dictionary.h <https://github.com/godotengine/godot/blob/master/core/dictionary.h>`__
|
||||
- `core/array.h <https://github.com/godotengine/godot/blob/master/core/array.h>`__
|
||||
|
||||
@@ -99,7 +99,7 @@ when:
|
||||
:ref:`Control.set_focus_mode() <class_Control_set_focus_mode>`.
|
||||
|
||||
This function is
|
||||
`Control._input_event(event) <https://github.com/okamstudio/godot/wiki/class_control#_input_event>`__.
|
||||
:ref:`Control._input_event() <class_Control__input_event>`.
|
||||
Simply override it in your control. No processing needs to be set.
|
||||
|
||||
::
|
||||
|
||||
@@ -249,7 +249,7 @@ certain threshold), the character can be determined to be there.
|
||||
|
||||
A more complete demo can be found in the demo zip distributed with the
|
||||
engine, or in the
|
||||
https://github.com/okamstudio/godot/tree/master/demos/2d/kinematic_char.
|
||||
https://github.com/godotengine/godot/tree/master/demos/2d/kinematic_char.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -44,10 +44,10 @@ resizing or stretching the screen. This transform is used internally by
|
||||
the :ref:`doc_multiple_resolutions`, but can also be requested to the viewport.
|
||||
|
||||
Input events received in the
|
||||
`Node._input_event(ev) <https://github.com/okamstudio/godot/wiki/class_node#_input_event>`__
|
||||
:ref:`Node._input_event() <class_Node__input_event>`
|
||||
callback are multiplied by this transform, but lack the ones above. To
|
||||
convert InputEvent coordinates to local CanvasItem coordinates, the
|
||||
`CanvasItem.make_input_local(ev) <https://github.com/okamstudio/godot/wiki/class_canvasitem#make_input_local>`__
|
||||
:ref:`CanvasItem.make_input_local() <class_CanvasItem_make_input_local>`
|
||||
function was added for convenience.
|
||||
|
||||
Transform Order
|
||||
|
||||
@@ -64,7 +64,7 @@ Blender also has built-in collada support, but It's really broken and
|
||||
should not be used either.
|
||||
|
||||
Godot provides a `Python
|
||||
Plugin <https://github.com/okamstudio/godot/tree/master/tools/export/blender25>`__
|
||||
Plugin <https://github.com/godotengine/godot/tree/master/tools/export/blender25>`__
|
||||
that will do a much better job at exporting the scenes.
|
||||
|
||||
The import process
|
||||
|
||||
@@ -285,9 +285,8 @@ resource.
|
||||
Example class
|
||||
-------------
|
||||
|
||||
You can find an example class for loading resources in threads
|
||||
`here <https://github.com/okamstudio/godot/wiki/media/resource_queue.gd>`__.
|
||||
Usage is as follows:
|
||||
You can find an example class for loading resources in threads here:
|
||||
:download:`resource_queue.gd </files/resource_queue.gd>`. Usage is as follows:
|
||||
|
||||
::
|
||||
|
||||
@@ -365,6 +364,5 @@ Example:
|
||||
queue.cancel_resource("res://zone_2.xml")
|
||||
|
||||
**Note**: this code in its current form is not tested in real world
|
||||
scenarios. Find me on IRC (punto on irc.freenode.net) or e-mail me
|
||||
(punto@okamstudio.com) for help.
|
||||
scenarios. Ask punto on IRC (#godotengine on irc.freenode.net) for help.
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ application/name and append it the locale identifier. For example:
|
||||
.. image:: /img/localized_name.png
|
||||
|
||||
As always, If you don't know the code of a language or zone, `check the
|
||||
list <https://github.com/okamstudio/godot/wiki/locales>`__.
|
||||
list :ref:`doc_locales`.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -189,7 +189,7 @@ inside the editor:
|
||||
|
||||
Make sure to check the viewport demos! Viewport folder in the demo.zip
|
||||
available to download, or
|
||||
https://github.com/okamstudio/godot/tree/master/demos/viewport
|
||||
https://github.com/godotengine/godot/tree/master/demos/viewport
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,19 +4,17 @@ Physics Ray Casting and Queries (2D and 3D)
|
||||
===========================================
|
||||
|
||||
Introduction
|
||||
~~~~~~~~~~~~
|
||||
------------
|
||||
|
||||
One of the most common tasks in game development is casting a ray (or
|
||||
custom shaped object) and see what it hits. This enables complex
|
||||
behaviors, AI, etc. to take place.
|
||||
|
||||
This tutorial will explain how to do this in 2D and 3D.
|
||||
behaviors, AI, etc. to take place. This tutorial will explain how to
|
||||
do this in 2D and 3D.
|
||||
|
||||
Godot stores all the low level game information in servers, while the
|
||||
scene is just a frontend. As such, ray casting is generally a
|
||||
lower-level task. For simple raycasts, node such as
|
||||
:ref:`RayCast <class_RayCast>` and
|
||||
:ref:`RayCast2D <class_RayCast2D>`
|
||||
:ref:`RayCast <class_RayCast>` and :ref:`RayCast2D <class_RayCast2D>`
|
||||
will work, as they will return every frame what the result of a raycast
|
||||
is.
|
||||
|
||||
@@ -24,37 +22,31 @@ Many times, though, ray-casting needs to be a more interactive process
|
||||
so a way to do this by code must exist.
|
||||
|
||||
Space
|
||||
~~~~~
|
||||
-----
|
||||
|
||||
In the physics world, Godot stores all the low level collision and
|
||||
physics information in a *space*. The current 2d space (for 2D Physics)
|
||||
can be obtained by calling
|
||||
`CanvasItem.get_world_2d().get_space() <https://github.com/okamstudio/godot/wiki/class_canvasitem#get_world_2d>`__.
|
||||
For 3D, it's
|
||||
`Spatial.get_world().get_space() <https://github.com/okamstudio/godot/wiki/class_spatial#get_world>`__.
|
||||
:ref:`CanvasItem.get_world_2d().get_space() <class_CanvasItem_get_world_2d>`.
|
||||
For 3D, it's :ref:`Spatial.get_world().get_space() <class_Spatial_get_world>`.
|
||||
|
||||
The resulting space
|
||||
:ref:`RID <class_RID>` can be used
|
||||
in
|
||||
:ref:`PhysicsServer <class_PhysicsServer>`
|
||||
and
|
||||
:ref:`Physics2DServer <class_Physics2DServer>`
|
||||
respectively for 3D and 2D.
|
||||
The resulting space :ref:`RID <class_RID>` can be used in
|
||||
:ref:`PhysicsServer <class_PhysicsServer>` and
|
||||
:ref:`Physics2DServer <class_Physics2DServer>` respectively for 3D and 2D.
|
||||
|
||||
Acessing Space
|
||||
~~~~~~~~~~~~~~
|
||||
Acessing space
|
||||
--------------
|
||||
|
||||
Godot physics runs by default in the same thread as game logic, but may
|
||||
be set to run on a separate thread to work more efficiently. Due to
|
||||
this, the only time accessing space is safe is during the
|
||||
`Node._fixed_process(delta) <https://github.com/okamstudio/godot/wiki/class_node#_fixed_process>`__
|
||||
:ref:`Node._fixed_process() <class_Node__fixed_process>`
|
||||
callback. Accessing it from outside this function may result in an error
|
||||
due to space being *locked*.
|
||||
|
||||
To perform queries into physics space, the
|
||||
:ref:`Physics2DDirectSpaceState <class_Physics2DDirectSpaceState>`
|
||||
and
|
||||
:ref:`PhysicsDirectSpaceState <class_PhysicsDirectSpaceState>`
|
||||
and :ref:`PhysicsDirectSpaceState <class_PhysicsDirectSpaceState>`
|
||||
must be used.
|
||||
|
||||
In code, for 2D spacestate, this code must be used:
|
||||
@@ -79,8 +71,8 @@ For 3D:
|
||||
func _fixed_process(delta):
|
||||
var space_state = get_world().get_direct_space_state()
|
||||
|
||||
Raycast Query
|
||||
~~~~~~~~~~~~~
|
||||
Raycast query
|
||||
-------------
|
||||
|
||||
For performing a 2D raycast query, the method
|
||||
:ref:`Physics2DDirectSpaceState.intersect_ray() <class_Physics2DDirectSpaceState_intersect_ray>`
|
||||
@@ -117,8 +109,8 @@ The collision result dictionary, when something hit, has this format:
|
||||
|
||||
# in case of 3D, Vector3 is returned.
|
||||
|
||||
Collision Exceptions
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
Collision exceptions
|
||||
--------------------
|
||||
|
||||
It is a very common case to attempt casting a ray from a character or
|
||||
another game scene to try to infer properties of the world around it.
|
||||
@@ -141,11 +133,10 @@ collisionobject based node:
|
||||
var space_state = get_world().get_direct_space_state()
|
||||
var result = space_state.intersect_ray( get_global_pos(), enemy_pos, [ self ] )
|
||||
|
||||
The extra argument is a list of exceptions, can be objects (need Godot
|
||||
1.1beta2+ for this) or RIDs.
|
||||
The extra argument is a list of exceptions, can be objects or RIDs.
|
||||
|
||||
3D Ray Casting From Screen
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
3D ray casting from screen
|
||||
--------------------------
|
||||
|
||||
Casting a ray from screen to 3D physics space is useful for object
|
||||
picking. There is not much of a need to do this because
|
||||
@@ -153,8 +144,7 @@ picking. There is not much of a need to do this because
|
||||
has an "input_event" signal that will let you know when it was clicked,
|
||||
but in case there is any desire to do it manually, here's how.
|
||||
|
||||
To cast a ray from the screen, the
|
||||
:ref:`Camera <class_Camera>` node
|
||||
To cast a ray from the screen, the :ref:`Camera <class_Camera>` node
|
||||
is needed. Camera can be in two projection modes, perspective and
|
||||
orthogonal. Because of this, both the ray origin and direction must be
|
||||
obtained. (origin changes in orthogonal, while direction changes in
|
||||
@@ -175,8 +165,5 @@ To obtain it using a camera, the following code can be used:
|
||||
var from = camera.project_ray_origin(ev.pos)
|
||||
var to = from + camera.project_ray_normal(ev.pos) * ray_length
|
||||
|
||||
Of course, remember that during _input(), space may be locked, so save
|
||||
your query for _fixed_process().
|
||||
|
||||
|
||||
|
||||
Of course, remember that during ``_input()``, space may be locked, so save
|
||||
your query for ``_fixed_process()``.
|
||||
|
||||
@@ -89,7 +89,7 @@ trigonometry already, prepare to embrace vectors!
|
||||
|
||||
In any case, obtaining an angle from a vector is easy and can be
|
||||
accomplished with trig.. er what was that? I mean, the
|
||||
`atan2(x,y) <https://github.com/okamstudio/godot/wiki/class_@gdscript#atan2>`__
|
||||
:ref:`atan2.atan2() <class_atan2_atan2>`
|
||||
function.
|
||||
|
||||
Vectors in Godot
|
||||
@@ -391,7 +391,7 @@ two vectors, we must do:
|
||||
What is this useful for? Well obtaining the angle directly is probably
|
||||
not as useful, but just being able to tell the angle is useful for
|
||||
reference. One example is in the `Kinematic
|
||||
Character <https://github.com/okamstudio/godot/blob/master/demos/2d/kinematic_char/player.gd#L83>`__
|
||||
Character <https://github.com/godotengine/godot/blob/master/demos/2d/kinematic_char/player.gd#L879>`__
|
||||
demo, when the character moves in a certain direction then we hit an
|
||||
object. How to tell if what we hit is the floor?
|
||||
|
||||
@@ -400,7 +400,7 @@ computed angle.
|
||||
|
||||
The beauty of this is that the same code works exactly the same and
|
||||
without modification in
|
||||
`3D <https://github.com/okamstudio/godot/blob/master/demos/3d/kinematic_char/cubio.gd#L64>`__.
|
||||
`3D <https://github.com/godotengine/godot/blob/master/demos/3d/kinematic_char/cubio.gd#L57>`__.
|
||||
Vector math is, in a great deal, dimemsion-amount-independent, so adding
|
||||
or removing an axis only adds very little complexity.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user