I would like to explain how the hookshot scripts work in the game because someone asked.
You can download the .blend to get the python script but let me explain it here because it is a bit confusing to read.
-
The right mouse button is pressed.
-
A ray checks if there is a wall directly in front of the player.
-
A timer is checked to see if the ropeshot is still firing.
-
An object which is parented to the character and at a position the ropeshot should be firing towards is recording its own x, y, and z position every frame.
-
These coordinates are taken from the object and given to the ropeshot spawner (an empty) which has been parented to the character’s wrist.
-
The empty subtracts these coordinates with its own coordinates to find the relative direction of the second object.
-
Then it sets the character’s velocity equal to this vector.
Steps 6-8 in code
def main():
import bge
cont = bge.logic.getCurrentController()
own = cont.owner
xpart = 2*(own["xshot"]-own["xpos"])
ypart = 2*(own["yshot"]-own["ypos"])
zpart = 2*(own["zshot"]-own["zpos"])
// it is times 2 just to make the charicter go faster
own.setLinearVelocity([xpart, ypart, zpart])
main()
8. It sets xshot (target position) and xpos (character position) before the script is run and only gets them once meaning that this script will do the same thing every time it is run for a single ropeshot use. This script is run every frame until the character faces a wall (step 2 above) or the ropeshot times out. This means your character will have the same velocity set every frame.
9. This entire process is run by a timer (but does not need to be) where right clicking sets the time to 0. All other events (spawning the collision free rope object, moving the character, canceling the movement, and deleting the rope) occur at set points in time and canceling the ropeshot (from facing a wall) just skips the timer to the end where it will just keep counting to infinity.
The other hookshot from the second half of the game works by similar mechanics but the reference object is a ball which is launched from the characters wrist and sends its own position when it hits an object. Then the script is run once to propel the character towards the object.
def main():
import bge
import math
from math import sqrt
cont = bge.logic.getCurrentController()
own = cont.owner
xpart = (own["xshot"]-own["xpos"]) //xshot is the position of the ball you launched
ypart = (own["yshot"]-own["ypos"]) //xpos is the character’s position
zpart = (own["zshot"]-own["zpos"])
totalses = sqrt(xpart*xpart+ypart*ypart+2*zpart*zpart)
divadivaden = totalses/35
xside = xpart/divadivaden
yside = ypart/divadivaden
zside = 1.4142*zpart/divadivaden
own.setLinearVelocity([xside, yside, zside])
main()
To fire the ball (which gives its position as xshot) it is deparented from the armature of the character and given a velocity by a motion actuator.
On the first frame of gameplay and after every time the hookshot is used, the ball has its rotation set so it will always fly in the same direction and is parented to the armature (don’t parent it in the editor, this causes problems).
def main():
import bge
cont = bge.logic.getCurrentController()
own = cont.owner
own.localOrientation = [[1.0, 0.0, 0.0], [ 0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
//this is a random orientation but that doesn’t matter as long as it is always the same orientation
//instead of trying to set this orientation right just adjust the motion actuator
xpos = -.1
ypos = 1 // sorry but I honestly don’t remember why this part works?
zpos = 0 // maybe this executes after it is parented so these are local coordinates.
own.position = (xpos,ypos,zpos)
main()
If you have any questions just ask.