# Dealing with special effect orientation (new functions)

#### Ofel

Level 13
I would like to use special effect as my projectile missile rather than dummy unit. The problem here is about the orientation.
I used this to change the dummy unit orientation:
JASS:
``````function SetUnitPitch takes unit targetUnit, real pitch returns nothing
local integer i = R2I(pitch * bj_RADTODEG + 90.5)
if (179 < i) then
set i = 179
elseif (0 > i) then
set i = 0
endif
call SetUnitAnimationByIndex(targetUnit, i)
endfunction``````

But I would prefer to use the new function:
`call BlzSetSpecialEffectOrientation(fx, 0, pitch, roll)`
I don't find function to change the facing angle so I assumed that roll is equal to unit facing angle.

I tried testing this function on a single special effect, but I got a problem.
If I set pitch to 90 (with roll = 0), it works.
If I set pitch to 90 (with roll = 90), pitch won't change.
I can only change pitch to anything I want if roll is 0.

#### Attachments

• special effect orientation test.w3x
17.3 KB · Views: 52
Last edited:

#### Tasyen

Level 33
WarEditor wrote a vjass function calcing the facing.

JASS:
``````    // movement is a Vector 3D
// new is the target position (Vector 3D)
// fx.position is the fx position (Vector 3D)
set movement =  new - fx.position
call fx.setOrientation(movement.angleX,movement.angleY,movement.angleZ)
// those are the 'angle' method operators from the Vector 3D struct
method operator angleZ takes nothing returns real
return Atan2(this.y,this.x)
endmethod

method operator angleY takes nothing returns real
local real ix = Math.abs(this.x)
local real iy = Math.abs(this.y)
local real px = (1-(iy/(ix+iy)))
if not (this.x == 0) then
return -Atan(this.z/this.x)*px
else
return 0.
endif
endmethod

method operator angleX takes nothing returns real
local real ix = Math.abs(this.x)
local real iy = Math.abs(this.y)
local real py = (1-(ix/(ix+iy)))

if not (this.y == 0) then
return Atan(this.z/this.y)*py
else
return 0.
endif
endmethod``````

I transformed it into normal jass.

call EffectFacing(eff, oldX, oldY, oldZ , newX, newY, newZ) Then the effect should face based on current movement.

JASS:
``````Credits: Wareditor who wrote the orginal version in vJass.

function angleX takes real x, real y, real z returns real
local real ix =  RAbsBJ(x)
local real iy = RAbsBJ(y)
local real py = (1-(ix/(ix+iy)))

if not (y == 0) then
return Atan(z/y)*py
else
return 0.0
endif
endfunction
function angleY takes real x, real y, real z returns real
local real ix =  RAbsBJ(x)
local real iy = RAbsBJ(y)
local real px = (1-(iy/(ix+iy)))
if not (x == 0) then
return -Atan(z/x)*px
else
return 0.0
endif
endfunction
function angleZ takes real x, real y, real z returns real
return Atan2(y,x)
endfunction

function EffectFacing takes effect eff, real currentX, real currentY, real currentZ, real targetX, real targetY, real targetZ returns nothing
//calculate the change of x, y, z
local real x = targetX - currentX
local real y = targetY - currentY
local real z = targetZ - currentZ
call BlzSetSpecialEffectOrientation(eff, angleX(x,y,z), angleY(x,y,z), angleZ(x,y,z))
endfunction``````

Maybe one of this 2 is of use for you.
Edit: swaped the order of mine.

Last edited:

#### Ofel

Level 13
WarEditor wrote a vjass function calcing the facing.

JASS:
``````    // movement is a Vector 3D
// new is the target position (Vector 3D)
// fx.position is the fx position (Vector 3D)
set movement =  new - fx.position
call fx.setOrientation(movement.angleX,movement.angleY,movement.angleZ)
// those are the 'angle' method operators from the Vector 3D struct
method operator angleZ takes nothing returns real
return Atan2(this.y,this.x)
endmethod

method operator angleY takes nothing returns real
local real ix = Math.abs(this.x)
local real iy = Math.abs(this.y)
local real px = (1-(iy/(ix+iy)))
if not (this.x == 0) then
return -Atan(this.z/this.x)*px
else
return 0.
endif
endmethod

method operator angleX takes nothing returns real
local real ix = Math.abs(this.x)
local real iy = Math.abs(this.y)
local real py = (1-(ix/(ix+iy)))

if not (this.y == 0) then
return Atan(this.z/this.y)*py
else
return 0.
endif
endmethod``````

I transformed it into normal jass.

call EffectFacing(eff, oldX, oldY, oldZ , newX, newY, newZ) Then the effect should face based on current movement.

JASS:
``````Credits: Wareditor who wrote the orginal version in vJass.

function EffectFacing takes effect eff, real currentX, real currentY, real currentZ, real targetX, real targetY, real targetZ returns nothing
//calculate the change of x, y, z
local real x = targetX - currentX
local real y = targetY - currentY
local real z = targetZ - currentZ
call BlzSetEffectOrientation(eff, angleX(x,y,z), angleY(x,y,z), angleZ(x,y,z))
endfunction

function angleX takes real x, real y, real z returns real
local real ix =  RAbsBJ(x)
local real iy = RAbsBJ(y)
local real py = (1-(ix/(ix+iy)))

if not (this.y == 0) then
return Atan(z/y)*py
else
return 0.0
endif
endfunction
function angleY takes real x, real y, real z returns real
local real ix =  RAbsBJ(x)
local real iy = RAbsBJ(y)
local real px = (1-(iy/(ix+iy)))
if not (this.x == 0) then
return -Atan(z/x)*px
else
return 0.0
endif
endfunction
function angleZ takes real x, real y, real z returns real
return Atan2(y,x)
endfunction``````

Maybe one of this 2 is of use for you.
The x and y seems okay, but my projectile missile seems to have quite slower z speed.

JASS:
``````set tempX = targetX - sourceX
set tempY = targetY - sourceY
set tempZ = targetZ - sourceZ
// sourceX, sourceY, sourceZ are the last know position.
// targetX, targetY, targetZ are the where the missile is heading.

set dist = ClsR_GetMagnitude2D(tempX, tempY)
set angleZ = ClsR_AngleZ(tempX, tempY)
set anglePointsZ = ClsR_AnglePointsZ(dist, tempZ)

set targetX = sourceX + udg_ClsR_RocketsSpeedBase[udg_ClsR_Level[index]] * Cos(udg_ClsR_Facing[index]) * Cos(udg_ClsR_Pitch[index])
set targetY = sourceY + udg_ClsR_RocketsSpeedBase[udg_ClsR_Level[index]] * Sin(udg_ClsR_Facing[index]) * Cos(udg_ClsR_Pitch[index])
set targetZ = sourceZ + udg_ClsR_RocketsSpeedBase[udg_ClsR_Level[index]] * Sin(udg_ClsR_Pitch[index])
set udg_ClsR_posX[index] = targetX + udg_ClsR_RocketsTurnAcceleration[udg_ClsR_Level[index]] * Cos(angle) * Cos(angleZ)
set udg_ClsR_posY[index] = targetY + udg_ClsR_RocketsTurnAcceleration[udg_ClsR_Level[index]] * Sin(angle) * Cos(angleZ)
set udg_ClsR_posZ[index] = targetZ + udg_ClsR_RocketsTurnAcceleration[udg_ClsR_Level[index]] * Sin(angleZ)

set tempX = udg_ClsR_posX[index] - sourceX
set tempY = udg_ClsR_posY[index] - sourceY
set tempZ = udg_ClsR_posZ[index] - sourceZ

call ClsR_SetEffectOrientation(udg_ClsR_rocketFx[index], tempX, tempY, tempZ)
set udg_ClsR_Pitch[index] = udg_ClsR_newFxOrientationAngle[2]
set udg_ClsR_Facing[index] = udg_ClsR_newFxOrientationAngle[3]``````

JASS:
``````function ClsR_SetEffectOrientation takes effect fx, real x, real y, real z returns nothing
local real ax
local real ay
local real az
local real px
local real py

if x == 0 and y == 0 then
if z > 0 then
set ax = -bj_PI*0.5
else
set ax = bj_PI*0.5
endif
elseif z != 0 then
set ax = ClsR_RAbs(x)
set ay = ClsR_RAbs(y)
set px = ax / (ax + ay)
set py = 1 - px
if y == 0 then
set ax = 0
else
set ax = Atan(z/y)*py
endif
if x == 0 then
set ay = 0
else
set ay = -Atan(z/x)*px
endif
endif
set az = Atan2(y, x)
call BlzSetSpecialEffectOrientation(fx, ax, ay, az)
set udg_ClsR_newFxOrientationAngle[1] = ax
set udg_ClsR_newFxOrientationAngle[2] = ay
set udg_ClsR_newFxOrientationAngle[3] = az
endfunction``````

Last edited:

#### Wareditor

Level 14
Here is an update version in Wurst: wurstbin

#### Ofel

Level 13
Here is an update version in Wurst: wurstbin
I don't know where did I done wrong but the z speed seems too low.

#### Wareditor

Level 14
The code I posted has nothing to do with speed. It will set the special effect's orientation to the given orientation.

Level 13
Right

Thank you guys.

#### Devalut

Level 24
Right

Thank you guys.

Beg your pardon Ofel, but can you elaborate your solution for us?

#### Ofel

Level 13
Beg your pardon Ofel, but can you elaborate your solution for us?
This is the solution I found:
JASS:
``````//Credit goes to Wareditor
function SetEffectOrientation takes effect fx, real x, real y, real z returns nothing
local real ax
local real ay
local real az
local real px
local real py

if x == 0 and y == 0 then
if z > 0 then
set ax = -bj_PI*0.5
else
set ax = bj_PI*0.5
endif
elseif z != 0 then
set ax = RAbsBJ(x)
set ay = RAbsBJ(y)
set px = ax / (ax + ay)
set py = 1 - px
if y == 0 then
set ax = 0
else
set ax = Atan(z/y)*py
endif
if x == 0 then
set ay = 0
else
set ay = -Atan(z/x)*px
endif
endif
set az = Atan2(y, x)

// ax = yaw angle
// ay = pitch angle
// az = roll angle
call BlzSetSpecialEffectOrientation(fx, ax, ay, az)
endfunction``````

In my case:
JASS:
``````set vectorX = moveX - posX
set vectorY = moveY - posY
set vectorZ = moveZ - posZ
// (moveX, moveY, moveZ) is where the effect is going to move.
// (posX, posY, posZ) is the current position.

call SetEffectOrientation(fx, vectorX, vectorY, vectorZ)``````

#### Devalut

Level 24
Excellent!!!
It is a Cardinal sin to post things like "nvm I found fix" or "pm me for the fix- DATED 1998-01-22" after finding the solution to a problem.

Level 13
I can't sin.

Replies
5
Views
579
Replies
7
Views
1K
Replies
6
Views
1K
Replies
4
Views
950