I created a separate project to test this guy. I essentially have floor tiles made of 2 units so if he needs to turn I want it to be in symmetry with the tile. There is probably a better way to do this.
this is what I use to construct the path:
extends Spatial
var ldmon = load("res://monster1.tscn")
var mpath = [[2, -3], [1, -3], [0, -3], [0, -2], [0, -1]]
func _ready():
var monin = ldmon.instance()
#monin.global_transform.origin = Vector3(4, 0, -6)
monin.name = "Monster"
monin.set_path(mpath)
add_child(monin)
This is what I use in the monster:
extends Spatial
onready var player_anim = get_child(3)
var tracPath = []
var indnum = 0
var anim = false
var firus: bool
var secus: bool
var turning: bool = false
var movone = true
var firrot = 0
var secrot = 0
var turpar = 0
var rotsig: bool = false
var lenmoved = 0
func stopMov():
player_anim.stop(false)
anim = false
func set_path(var path):
tracPath = path
global_transform.origin = Vector3(path[0][0] * 2, 0, path[0][1] * 2)
setdir()
anim = true
func _physics_process(delta):
if anim:
if turning:
turpar += delta * .5
var crot = get_lerp(firrot, secrot, turpar)
rotate_y(crot)
if is_instance_valid(player_anim):
if not player_anim.is_playing():
player_anim.play("metarigAction")
if turpar >= 1:
var movam = 1 - (turpar - (delta * .5))
turpar = 0
turning = false
rotsig = false
var fvecx = global_transform.basis.z.x
var fvecz = global_transform.basis.z.z
global_transform.origin.x += fvecx * movam
global_transform.origin.z += fvecz * movam
indnum += 1
else:
var fvecx = global_transform.basis.z.x
var fvecz = global_transform.basis.z.z
# deg2rad(45) = 2 * PI * R / 4 * movspeed
global_transform.origin.x += fvecx * delta * deg2rad(45)
global_transform.origin.z += fvecz * delta * deg2rad(45)
else:
if is_instance_valid(player_anim):
if not player_anim.is_playing():
player_anim.play("metarigAction")
lenmoved += delta * .5
if (lenmoved >= 1 and movone) or (lenmoved >= 2 and not movone):
var movam = 0
if movone:
movam = 1 - (lenmoved - (delta * .5))
if rotsig:
movam = 0
turning = true
else:
movam = 2 - (lenmoved - (delta * .5))
setdir()
lenmoved = 0
movone = not movone
var fvecx = global_transform.basis.z.x
var fvecz = global_transform.basis.z.z
global_transform.origin.x += fvecx * movam
global_transform.origin.z += fvecz * movam
else:
var fvecx = global_transform.basis.z.x
var fvecz = global_transform.basis.z.z
global_transform.origin.x += fvecx * delta * .5
global_transform.origin.z += fvecz * delta * .5
func get_mrotation(var xdir, var zdir):
var sigx = sign(xdir)
var sigz = sign(zdir)
var retv = 0
if sigx == 0:
if sigz == 1:
retv = 270
else:
retv = 90
else:
if sigx == 1:
retv = 0
else:
retv = 180
print(Vector2(sigx, sigz))
print(retv)
return retv
#-90 -1, 0, 0
#0 0, 0, 1
#90 1, 0, 0
#180 0, 0, -1
func get_lerp(var rot1, var rot2, var fac):
if (rot1 == 0 and rot2 == 270) or (rot2 == 0 and rot1 == 270):
if rot1 == 0:
rot1 = 360
else:
rot2 = 360
return lerp(rot1, rot2, fac)
func setdir():
var dirx1 = 0
var dirz1 = 0
var dirx2 = 0
var dirz2 = 0
if indnum + 1 < tracPath.size():
dirx1 = tracPath[indnum + 1][0] - tracPath[indnum][0]
dirz1 = tracPath[indnum + 1][1] - tracPath[indnum][1]
firus = true
else:
firus = false
if indnum + 2 < tracPath.size():
dirx2 = tracPath[indnum + 2][0] - tracPath[indnum + 1][0]
dirz2 = tracPath[indnum + 2][1] - tracPath[indnum + 1][1]
secus = true
else:
secus = false
var mrot = 0
if secus:
mrot = get_mrotation(dirx1, dirz1)
if dirx1 == dirx2 and dirz1 == dirz2:
rotsig = false
else:
rotsig = true
firrot = mrot
secrot = get_mrotation(dirx2, dirz2)
rotate_y(mrot)
else:
rotsig = false
if firus:
mrot = get_mrotation(dirx1, dirz1)
rotate_y(mrot)