# Axe (cliff notes) - using the official Axe Package in Adventure Games

Axe (cliff notes) - using the official Axe Package in Adventure Games

this game is published and re-mixable

prerequisite: Inventory Tutorial
ref: Crayta Tutorial: Making Smashable Loot Boxes

Create Game: Starter: Adventure

Install

Axe Package

  • search for axe
  • check Crayta Packages
  • click Install
Axe Package

Sections

  • Smashable Loot Boxes
  • Chopping Trees

- Smashable Loot Boxes (mirrors Andy’s video tutorial) -

Add Axe to Inventory Defaults (video used wrench)

User Inventory Script Folder Defaults

Add crate to world

  • attach crateSmashScript (see below)
  • check Damage Enabled
  • On Destroyed (fill in after resourceSpawner is added)
    resourceSpawner1 / picksupScript / ShowPickup
crate - World Tree crate properties

crateSmashScript

local CrateSmashScript = {}

CrateSmashScript.Properties = {
    { name = "OnDestroyed", type = "event", tooltip = "Fires when this entity is destroyed" },
    { name = "health", type = "number", default = 600 }
}

function CrateSmashScript:OnDamage(damageAmount, damageCauser, hitResult)
    print("Crate was damaged")
    self.properties.health = self.properties.health - damageAmount
    if self.properties.health <= 0 then
        self:GetEntity().visible = false
        self:GetEntity().collisionEnabled = false
    
		self.properties.OnDestroyed:Send()
    end
end

return CrateSmashScript

Add resource spawner

  • uncheck Respawning
  • uncheck Show on Init
  • fill in On Destroyed on the crateSmashScript (above)
resourceSpawner - World Tree resourceSpawner Properties

- Chopping Trees for Logs -

Duplicate Templates

  • Duplicate Resource Spawner as Resource Spawner Log
  • Duplicate Shop Resource as Shop Resource Log

Resource Spawner Log

  • change Name - Resource Spawner Log
  • change Mesh Asset - Log (Short)

pickupSpawnerScript

  • uncheck Respawning
Resource Spawner Log pickupSpawnerScript

Shop Resource Log

  • change Name - Shop Resource Log

inventoryItemSpecScript

  • change Friendly Name - Resource Log
  • change Icon Asset - Log (Short)
Shop Resource Log inventoryItemSpecScript

Tree creation

  • add tree mesh to world
  • (appleTreeAutumn is used in this example)
  • add under tree
    • 3 locators named dropLocator1-3
    • 3 locators named resourceLocator1-3
    • spread locators away from tree
  • add 3 scripts (see code below for scripts)
    • hitableScript (damageEnabled is true in script)
    • wobbleScript
    • respawnEntityScript

hitableScript

  • Hit Effect = Impact Wood
  • Hitable Template = Axe
  • On Hit
    appleTreeAutumn1 / wobbleScript / DoWobble
  • Resource Template = Resource Spawner Log
  • Resource Locator = add the 3 resourceLocators from above

respawnEntityScript

  • On Respawn
    appleTreeAutumn1 / hitableScript / Reset
appleTreeAutumn1 appleTreeAutumn1 - World Tree
hitableScript wobbleScript

respawnEntityScript

Notes:

  • this is a cliff note.
  • change things as desired and test.
  • make a template after customizing.

hitableScript

local HitableScript = {}

-- Script properties are defined here
HitableScript.Properties = {	
	{name = "maxHealth", type = "number", default = 1000},
	{name = "health", type="number", editable =false},
	{name = "hitEffect", type="effectasset"},
	{name = "hitableTemplate", type="template"},	
	{name = "onHit", type="event"},
	
	{name = "canDropItems", type="boolean", default = false},
	{name = "dropTemplate", type="template", visibleIf = function(properties) return properties.canDropItems end},
	{name = "dropChance", type="number", default = 50, visibleIf = function(properties) return properties.canDropItems end},
	{name = "dropLocator", type="entity", container="array", visibleIf = function(properties) return properties.canDropItems end},
	
	{name = "resourceTemplate", type="template"},	
	{name = "resourceLocator", type="entity", container="array"},
}

--This function is called on the server when this entity is created
function HitableScript:Init()
	self:Reset()
	self:GetEntity().damageEnabled = true
end

function HitableScript:Reset()
	self.properties.health = self.properties.maxHealth
end

function HitableScript:OnDamage(dmg, fromEntity)

	self.properties.health = self.properties.health - dmg
	
	self:GetEntity():PlayEffectAtLocation(self:GetEntity():GetPosition(), Rotation.Zero, self.properties.hitEffect)
	
	-- play wobble effect
	self.properties.onHit:Send()
	
	if self.properties.canDropItems then
		local rand = math.random(1,100)
		if rand >= self.properties.dropChance then
			GetWorld():Spawn(self.properties.dropTemplate, self:GetRandomDropLocator():GetPosition(), Rotation.Zero)
		end
	end
	
	
	if self.properties.health <= 0 then
		self:GetEntity():SendToScripts("HideEntity")
		
		-- drop resources
		for i=1, #self.properties.resourceLocator, 1 do
			GetWorld():Spawn(self.properties.resourceTemplate, self.properties.resourceLocator[i]:GetPosition(), Rotation.Zero)
		end
	end
end

function HitableScript:GetRandomDropLocator()
	return self.properties.dropLocator[math.random(1, #self.properties.dropLocator)]
end

return HitableScript

resapwnEntityScript

local RespawnEntityScript = {}

-- Script properties are defined here
RespawnEntityScript.Properties = {
	-- Example property
	{name = "respawnTime", type="number", default =10},
	{name = "onRespawn", type="event"}
}

--This function is called on the server when this entity is created
function RespawnEntityScript:Init()
end

function RespawnEntityScript:HideEntity()

	self:GetEntity().visible = false
	self:GetEntity().collisionEnabled = false
	
	self:Schedule(
		function()
			Wait(self.properties.respawnTime)
			self:GetEntity().visible = true
			self:GetEntity().collisionEnabled = true
			self.properties.onRespawn:Send()
		end
	)

end

return RespawnEntityScript

wobbleScript

local WobbleScript = {}

WobbleScript.Properties = {
	{name = "numWobbles", type = "number", default = 3},
	{name = "maxRotation", type = "rotation", default = Rotation.New(45, 0, 0)},
	{name = "totalTime", type = "number", default = 3},
}

function WobbleScript:DoWobble()
	if IsClient() then
		if self.wobbleSchedule then
			self:Cancel(self.wobbleSchedule)
			self:GetEntity():SetRelativeRotation(self.startRot)
		end
		
		self.wobbleSchedule = self:Schedule(
			function()
				self.startRot = self:GetEntity():GetRelativeRotation()
				local maxRot = self.properties.maxRotation
				local wobbleTime = self.properties.totalTime / self.properties.numWobbles
				local t = 0
				while t < self.properties.totalTime do
					t = t + Wait()
					local prog = math.sin(t * math.pi * self.properties.numWobbles)
					local amount = prog * math.lerp(1, 0, t / self.properties.totalTime)
					local rotOffset = Rotation.New(maxRot.pitch * amount, maxRot.yaw * amount, maxRot.roll * amount)
					self:GetEntity():SetRelativeRotation(self.startRot + rotOffset)
				end
				self:GetEntity():SetRelativeRotation(self.startRot)
			end
		)
	else
		self:SendToAllClients("DoWobble")
	end
end

return WobbleScript