PhysicsObject
A CoreObject with simulated physics that can interact with players and other objects. PhysicsObject also implements the Damageable interface.
Properties
Property Name | Return Type | Description | Tags |
---|---|---|---|
team | integer | Assigns the physics object to a team. Value range from 0 to 4 . 0 is neutral team. | Read-Write |
isTeamCollisionEnabled | boolean | If false , and the physics object has been assigned to a valid team, players on that team will not collide with the object. | Read-Write |
isEnemyCollisionEnabled | boolean | If false , and the physics object has been assigned to a valid team, players on other teams will not collide with the object. | Read-Write |
hitPoints | number | Current amount of hit points. | Read-Write |
maxHitPoints | number | Maximum amount of hit points. | Read-Write |
isDead | boolean | True if the object is dead, otherwise false. Death occurs when damage is applied which reduces hit points to 0, or when the Die() function is called. | Read-Only |
isImmortal | boolean | When set to true , this object cannot die. | Read-Write |
isInvulnerable | boolean | When set to true , this object does not take damage. | Read-Write |
destroyOnDeath | boolean | When set to true , this object will automatically be destroyed when it dies. | Read-Only |
destroyOnDeathDelay | number | Delay in seconds after death before this object is destroyed, if destroyOnDeath is set to true . Defaults to 0. | Read-Only |
destroyOnDeathClientTemplateId | string | Optional asset ID of a template to be spawned on clients when this object is automatically destroyed on death. | Read-Only |
destroyOnDeathNetworkedTemplateId | string | Optional asset ID of a networked template to be spawned on the server when this object is automatically destroyed on death. | Read-Only |
Functions
Function Name | Return Type | Description | Tags |
---|---|---|---|
ApplyDamage(Damage) | None | Damages the object, unless it is invulnerable. If its hit points reach 0 and it is not immortal, it dies. | Server-Only |
Die([Damage]) | None | Kills the object, unless it is immortal. The optional Damage parameter is a way to communicate cause of death. | Server-Only |
Events
Event Name | Return Type | Description | Tags |
---|---|---|---|
damagedEvent | Event <PhysicsObject object, Damage damage> | Fired when the object takes damage. | Server-Only |
diedEvent | Event <PhysicsObject object, Damage damage> | Fired when the object dies. | Server-Only |
hitPointsChangedEvent | Event <PhysicsObject object, number previousHitPoints> | Fired when there's a change in hit points on the object. | Server-Only |
collidedEvent | Event <PhysicsObject object, HitResult hitResult> | Fired when the object collides with another object. The HitResult parameter describes the collision that occurred. | None |
Hooks
Hook Name | Return Type | Description | Tags |
---|---|---|---|
damageHook | Hook <PhysicsObject object, Damage damage> | Hook called when applying damage from a call to ApplyDamage() . The incoming damage may be modified or prevented by modifying properties on the damage parameter. | Server-Only |
Examples
Example using:
damagedEvent
diedEvent
Physics Objects are also of type Damageable
. In this example, a script is responsible for spawning a series of target dummies. One dummy is spawned each time the function SpawnDummy()
is called. Dummies are spawned on either the left or right side, randomly, and move towards the other side. Each time a target dummy takes damage, the team inflicting the damage scores 1 point.
local DUMMY_TEMPLATE = script:GetCustomProperty("DummyTarget")
local MOVEMENT_RANGE = 500
local MOVEMENT_DURATION = 5
function SpawnDummy()
-- Calculate the dummy's start position and movement destination
local startOffset = Vector3.New(0, MOVEMENT_RANGE, 0)
if math.random() < 0.5 then
startOffset = -startOffset
end
local pos = script:GetWorldPosition() + startOffset
local destination = pos - startOffset * 2
-- Spawn the target dummy
local dummy = World.SpawnAsset(DUMMY_TEMPLATE, {position = pos})
-- Tell the dummy to move towards the destination
dummy:MoveTo(destination, MOVEMENT_DURATION)
-- Listen to damage/death events
-- Save the event listeners so we can clean up later
local listeners = {}
table.insert(listeners,
dummy.damagedEvent:Connect(OnTargetDamaged)
)
table.insert(listeners,
dummy.diedEvent:Connect(OnTargetDied)
)
dummy.serverUserData.eventListeners = listeners
end
function OnTargetDamaged(dummy, damage)
if damage.sourcePlayer
and damage.sourcePlayer.team
then
-- The team dealing damage gains 1 point
Game.IncreaseTeamScore(damage.sourcePlayer.team, 1)
end
end
function OnTargetDied(dummy, damage)
-- Disconnect event listeners to avoid memory leak
for _,eventListener in ipairs(dummy.serverUserData.eventListeners) do
if eventListener.isConnected then
eventListener:Disconnect()
end
end
dummy.serverUserData.eventListeners = {}
end
See also: Damage.sourcePlayer | Game.IncreaseTeamScore | World.SpawnAsset | CoreObject.MoveTo | Vector3.New | Event.Connect | EventListener.Disconnect
Example using:
ApplyDamage
collidedEvent
In this example, a Physics Object takes 5 damage each time it collides with any object.
local PHYSICS_OBJECT = script.parent
local DAMAGE_AMOUNT = 5
function OnObjectCollided(obj, hitResult)
if not obj.isDead then
local dmg = Damage.New(DAMAGE_AMOUNT)
dmg.reason = DamageReason.MAP
if other:IsA("Player") then
dmg.sourcePlayer = hitResult.other
end
obj:ApplyDamage(dmg)
end
end
PHYSICS_OBJECT.collidedEvent:Connect(OnObjectCollided)
See also: Damage.New | HitResult.other | DamageableObject.isDead | CoreObject.parent | Other.IsA | Event.Connect
Example using:
Die
In this example, a Physics Object dies if it falls below the world. The world's bottom limit is here defined as -100 meters.
local PHYSICS_OBJECT = script.parent
function Tick()
if not PHYSICS_OBJECT.isDead then
local position = PHYSICS_OBJECT:GetWorldPosition()
if position.z < -10000 then
PHYSICS_OBJECT:Die()
end
end
-- Wait a little. It would be inefficient to run this logic each frame
Task.Wait(0.25)
end
See also: CoreObject.GetWorldPosition | DamageableObject.isDead | Vector3.z
Example using:
hitPoints
maxHitPoints
isDead
Physics Objects are also of type Damageable
. In this example, a progress bar is used to display the object's hit points. In case the object is dead, then the progress bar will be empty.
local PHYSICS_OBJECT = script:GetCustomProperty("PhysicsObject"):WaitForObject()
local UI_PROGRESS_BAR = script:GetCustomProperty("UIProgressBar"):WaitForObject()
function Tick()
local percent = 0
if PHYSICS_OBJECT.maxHitPoints > 0 and not PHYSICS_OBJECT.isDead then
percent = PHYSICS_OBJECT.hitPoints / PHYSICS_OBJECT.maxHitPoints
percent = CoreMath.Clamp(percent)
end
UI_PROGRESS_BAR.progress = percent
end
See also: UIProgressBar.progress | CoreMath.Clamp | CoreObject.GetCustomProperty | CoreObjectReference.WaitForObject
Example using:
isImmortal
isInvulnerable
This example demonstrates an architecture for keeping track of temporary status effects or buffs. Two functions are implemented for Physics Objects, MakeImmortal() and MakeInvulnerable(). Because the functions may be called multiple times with overlapping durations, it's important to keep count of the number of active copies of the effect and only revert the property when the counter returns to zero.
local PHYSICS_OBJECT = script:GetCustomProperty("PhysicsObject"):WaitForObject()
-- Makes the object immortal for a given duration
function MakeImmortal(duration)
PHYSICS_OBJECT.isImmortal = true
local cleanup = CountAndWait("immortal", duration)
if cleanup then
PHYSICS_OBJECT.isImmortal = false
end
end
-- Makes the object invulnerable for a given duration
function MakeInvulnerable(duration)
PHYSICS_OBJECT.isInvulnerable = true
local cleanup = CountAndWait("invulnerable", duration)
if cleanup then
PHYSICS_OBJECT.isInvulnerable = false
end
end
-- Function common to both implementations. Yields the thread
-- Returns True if no copies of the effect remain
local function CountAndWait(effectId, duration)
local userData = PHYSICS_OBJECT.serverUserData
if not userData[effectId] then
userData[effectId] = 0
end
userData[effectId] = userData[effectId] + 1
Task.Wait(duration)
userData[effectId] = userData[effectId] - 1
return userData[effectId] <= 0
end
-- Utility function that says if a specific effect is active or not
function IsActive(effectId)
local userData = PHYSICS_OBJECT.serverUserData
return userData[effectId] and userData[effectId] > 0
end
-- Utility function that gives the current count for a given effect
function GetEffectCount(effectId)
local userData = PHYSICS_OBJECT.serverUserData
if userData[effectId] then
return userData[effectId]
end
return 0
end
See also: CoreObject.serverUserData | Task.Wait
Example using:
isTeamCollisionEnabled
isEnemyCollisionEnabled
In this example, a Physics Sphere can be given a special "ghost" ability. During this effect, the sphere cannot be touched by enemies and goes straight through them. At the end of the effect collision with enemies is restored, but then collision with allies is disabled for a short period, as a drawback to the powerful effect. This effect depends on a team value having been assigned to the object previously. If the sphere's team is still 0 (default), then nothing should happen.
local PHYSICS_SPHERE = script.parent
local GHOST_DURATION_ENEMY = 1.5
local GHOST_DURATION_ALLY = 1
local isSuper = false
function MakeGhostBall()
if isSuper then return end
isSuper = true
PHYSICS_SPHERE.isEnemyCollisionEnabled = false
Task.Wait(GHOST_DURATION_ENEMY)
PHYSICS_SPHERE.isEnemyCollisionEnabled = true
PHYSICS_SPHERE.isTeamCollisionEnabled = false
Task.Wait(GHOST_DURATION_ALLY)
PHYSICS_SPHERE.isTeamCollisionEnabled = true
isSuper = true
end
See also: CoreObject.parent | Task.Wait
Example using:
team
collidedEvent
In this example, a Physics Sphere detects players bumping into it. Each time a player collides with the sphere its team is changed to equal the player's team. In the sphere's client context, an additional script keeps a watch on changes to the team property and adjusts the mesh's team to equal that of the physics object. This results in the sphere changing color to blue/red, depending on who touched it last.
-- Server script
local PHYSICS_SPHERE = script.parent
function OnPhysicsCollided(ball, hitResult)
if hitResult.other:IsA("Player") then
ball.team = hitResult.other.team
end
end
PHYSICS_SPHERE.collidedEvent:Connect(OnPhysicsCollided)
-- Client script
local PHYSICS_SPHERE = script:GetCustomProperty("PhysicsSphere"):WaitForObject()
local PHYSICS_SPHERE_MESH = script:GetCustomProperty("PhysicsSphereMesh"):WaitForObject()
function Tick()
if PHYSICS_SPHERE.team == 0 then
PHYSICS_SPHERE_MESH.isTeamColorUsed = false
else
PHYSICS_SPHERE_MESH.isTeamColorUsed = true
PHYSICS_SPHERE_MESH.team = PHYSICS_SPHERE.team
end
Task.Wait(0.1)
end
See also: CoreMesh.isTeamColorUsed | Player.team | HitResult.other | Other.IsA | Task.Wait | Event.Connect