Punkland
한국어
한국어
  • PUNKLAND
    • Punkland 소개
    • ⬆️업데이트 내역
      • 스튜디오 업데이트 내역
      • 앱 업데이트 내역
        • AI 자동번역 기능
      • 서버 업데이트 내역
      • 업데이트 아카이브
  • Punkland Studio
    • 📖시작하기
      • 펑크랜드 스튜디오 다운로드
      • 버전 확인 및 업데이트
      • 신규 프로젝트 생성
      • 맵 만들기
        • 신규 맵 생성
        • 하위 맵 생성
        • 맵 편집
      • 스튜디오 인터페이스
        • [파일]탭
        • [편집]탭
        • [보기]탭
        • [게임]탭
        • [도구]탭
      • 테스트 플레이 진행
      • 게임 출시하기
    • 💻기본 제작 가이드
      • 데이터베이스
      • 리소스 관리자
      • 레이아웃 관리자
      • MP3 -> OGG 변환기
      • 번역파일 내보내기
      • 번역파일 불러오기
      • 스크립트
      • 리소스 마켓
      • 데이터 내보내기
        • 데이터 불러오기
      • 도움말
      • 프로젝트 관리
      • 대사 꾸미기
      • GM 명령어
      • 스탯
      • 피해량 공식
      • 아이템 조건식
      • 팁과 노하우
      • 예제 게임
      • 펑크랜드 네이버 카페
      • 자주 묻는 질문
    • 👑심화 제작 가이드
      • 탑메뉴 관리자
      • 리소스 관리자
      • 스프라이트 관리자
      • 레이아웃 관리자
      • 이벤트 페이지 관리자
      • 데이터베이스
      • 스파인 적용법
    • 스크립트 튜토리얼
      • 사용 방법
      • [스크립트 도움말]
      • 서버 스크립트
        • ScriptClan
        • ScriptColor
      • 클라이언트 스크립트
      • 예제
        • 인터페이스 스크립팅
        • 몬스터 AI 스크립팅
        • 펫 AI 스크립팅
        • 파티클 스크립팅
    • 유튜브 튜토리얼
      • 펑크랜드 유튜브 강좌
    • Web3 튜토리얼
      • NFT 민팅하기
      • 게임에 외부 NFT 연결하기
      • 게임에 ERC-20 토큰 연결하기
    • Effective Punkland
      • 서버와 통신하기
      • RunLater 주의사항
      • HTTP 요청 보내기
    • 개발자 가이드라인
      • 정산정보 등록 및 변경
        • 미성년자 법정대리인 동의서
      • 매출 및 수익금 정산 가이드라인
      • 유료 아이템 판매 관련 안내
      • 뒷거래 부정행위 관련 안내
      • 마케팅 가이드라인
      • 게임 운영 가이드라인
      • 콜라보레이션 가이드라인
      • 공지사항/이벤트 & 푸시 안내
      • 인게임 광고 가이드라인
      • 지적재산권 권리 침해 관련 안내
      • 게임 라이브를 위한 심사 시스템
  • 바로가기
    • 스튜디오 다운로드
    • 펑크랜드 홈페이지
    • 펑크랜드 개발자 카페
    • 공식 디스코드
    • 공식 유튜브
Powered by GitBook
On this page
  1. Punkland Studio
  2. 스크립트 튜토리얼
  3. 예제

몬스터 AI 스크립팅

  • 몬스터 AI 스크립트는 프로젝트 폴더/ServerScripts에 위치한 Hello.lua와 같은 파일 이름으로 저장되어야 읽힙니다.

스크립트
설명

enemy

몬스터의 ScriptUnit을 나타냅니다.

ai

ScriptEnemyUnitAI에서 실행할 AI 행동을 나타냅니다.

event

실행될 로직을 확인합니다.

AI_INIT(-1)

몬스터 AI 등록 시 최초 실행

AI_UPDATE(0)

2초마다 계속 실행

AI_ATTACKED(1)

공격 시 한 번 실행

AI_DEAD(2)

사망 시 한 번 실행

data

공격 시에만 사용 가능하며 (event == 1)일 때 damage, 스킬 ID, 크리티컬 여부(true, false) 정보를 확인할 수 있습니다.

예제) 서버 스크립트 - 몬스터의 AI 설정

 Server.SetMonsterAI(
        22, --AI를 적용할 몬스터의 인덱스
        function(enemy,ai,event,data)
        -- 최초 몬스터 AI 등록 시 실행
        if(event == AI_INIT) then
                 ai.customData.test = 1;
        end
        if (event == AI_UPDATE) then
                --현재 필드의 유닛들 중에서 조건에 해당하는 유닛 반환
                --예) 유닛 hp가 100보다 적은 적이 있을 시 가져온다
                --ai.SetTargetUnit(
                --        enemy.field.FindUnit(enemy.x, enemy.y, 200,
                --       function(u)
                --                return u.hp <= 100
                --        end
                --, 0,enemy))
                
                --현재 필드의 유닛들 중에서 가장 작은 조건에 해당하는 유닛 반환
                --예) 플레이어 유닛 중에서 hp가 가장 적은 적을 가져온다
                --ai.SetTargetUnit(
                --        enemy.field.FindMinimumUnit(enemy.x, enemy.y, 200,
                --        function(u)
                --                return u.hp
                --        end
                --, 0,enemy))

                --현재 필드의 유닛들 중에서 가장 큰 조건에 해당하는 유닛 반환
                --예) 플레이어 유닛 중에서 hp가 가장 많은 적을 가져온다
                --ai.SetTargetUnit(
               --        enemy.field.FindMaximumUnit(enemy.x, enemy.y, 200,
                --        function(u)
                --               return u.hp
                --        end
                --, 0,enemy))
                
               --타깃이 정해지지 않았을 경우 가장 가까운 플레이어를 타깃으로 지정
                if( ai.GetTargetUnit() == nil) then
                        ai.SetNearTarget(0,200)
                end
                
                --맵에 플레이어가 하나도 없을 경우 null로 세팅
                if( enemy.field.playerCount <=0) then
                        ai.SetTargetUnit(nil)
                        
                --타깃이었던 플레이어가 맵을 나갈 경우 타깃 다시 지정
                elseif(enemy.field.GetUnit(ai.GetTargetUnitID()) == nil) then
                        ai.SetNearTarget(0,200)
                end
                
                --타깃이 있을 경우 타깃 방향으로 공격
                ai.UseSkill(22);

                --왼쪽 공격
                ai.UseSkill(22,Point(-1,0))

                --오른쪽 공격
                ai.UseSkill(22,Point(1,0))

                --위쪽 공격
                ai.UseSkill(22,Point(0,1))

                --아래쪽 공격
                ai.UseSkill(22,Point(0,-1))

                --해당 위치로 공격
                ai.UseSkillToPosition(24,Point(150,-150))
                
                --타겟이 없을 경우 예외 처리
                if(ai.GetTargetUnit() == nil) then
                        return
                end
                
                --타깃의 hp에 따른 추적 활성화/비활성화
                if(ai.GetTargetUnit().hp <=150) then
                        ai.SetFollowTarget(false)
                else
                        ai.SetFollowTarget(true)
               end
                
        end

       if (event == AI_ATTACKED) then
                enemy.Say('공격당했다. \n대미지: ' .. data.damage 
                .. '\n스킬ID: '..data.skillDataID
                .. '\n크리티컬여부: '..(data.critical and 'true' or 'false'))
                
                --공격한 유닛이 없을 경우 예외 처리
                if(ai.GetAttackedUnit() == nil) then
                        return
               end
                 --공격한 적의 hp를 확인하여 100보다 적을 경우 타깃 변경
                if(ai.GetAttackedUnit().hp <= 100) then
                        ai.SetTargetUnit(ai.GetAttackedUnit()) 
                end

        end

        if (event == AI_DEAD) then
                Server.SendSay('사망')
                --사망 후 특정 위치에서 부활
                enemy.RespawnAt(150,-150)
        end

end)

예제) 서버 스크립트 - 몬스터 AI 선공격 몬스터

function firstAttack(enemy,ai,event,data)
    if (event == 0) then -- 2초마다 실행되는 이벤트
    
        --맵에 플레이어가 하나도 없을 경우 null로 세팅
        if enemy.field.playerCount <=0 then
            ai.SetTargetUnit(nil)
            
        -- 타깃이 없거나 기존 타깃이던 유닛이 맵을 나갔거나 x 또는 y값 차이의 절댓값이 300을 넘어서면
        -- 타깃을 nil로 초기화하고 200 범위 내에서 타깃을 설정
        elseif (ai.GetTargetUnit()==nil)
               or (enemy.field.GetUnit(ai.GetTargetUnitID())==nil)
               or (math.abs(enemy.x-enemy.field.GetUnit(ai.GetTargetUnitID()).x) >= 300) 
               or (math.abs(enemy.y-enemy.field.GetUnit(ai.GetTargetUnitID()).y) >= 300) then
            
            if ai.GetTargetUnit() ~= nil then
                enemy.say('타깃이 사라졌군...')
            end
            
            ai.SetFollowTarget(false) --타깃이 사라지면 추적 비활성화
            ai.SetTargetUnit(nil)
            ai.SetNearTarget(0,200)

            -- 주변 탐색 후 타깃 발견 시(nil이 아니면), 추적 활성화(true), 메세지 출력
            if ai.GetTargetUnit() ~= nil then 
                ai.SetFollowTarget(true) 
                enemy.say('타깃' 발견! \n추적 시작!')
            end
        end
        
        --타깃 존재 시 타깃을 향해 스킬 10번 발사
        if ai.GetTargetUnit() ~= nil then
            ai.UseSkill(10)
        end
        
        --타깃 부재 시 예외 처리
        if ai.GetTargetUnit() == nil then
            return
        end
        
    end
    
    if (event == 1) then -- 몬스터가 공격을 받을 때마다 실행되는 이벤트
        --공격한 유닛이 없을 경우 예외 처리
        if ai.GetAttackedUnit() == nil then
            return
        else
            --기존 타깃 유닛과 공격 유닛이 같지 않을 경우 공격한 유닛을 타깃으로 지정 또는 변경하고 추적
            if ai.GetTargetUnit() ~= ai.GetAttackedUnit() then 
                ai.SetTargetUnit(ai.GetAttackedUnit())
                ai.SetFollowTarget(true)
                enemy.say('새로운 공격자를 추적한다...')
            end
            
            -- 몬스터 피격 시 10% 확률로 특수 공격 기술을 5번 시전 후 서버 전체에 메시지 출력
            if math.random(0,99) <= 9 then
                ai.UseSkill(5)
                Server.SendCenterLabel('<color=#FF0000>크롸롸!!</color>\n멍청한 보스 배던이 울부짖습니다!')
            end
        end
    end
        
end

Server.SetMonsterAI(1, firstAttack) -- 1번 몬스터에게 firstAttack 적용
Previous인터페이스 스크립팅Next펫 AI 스크립팅

Last updated 4 months ago