개인 자료란 (JE)

  서버 커뮤니티

Profile Resen 대표칭호 없음
Profile

질문하기 Java

플러그인 PlayerMoveEvent 관련 질문

2022.06.14 조회 수 545 추천 수 0
이해도 플러그인 
게임버전 (JE) 버킷, 기타 

제가 구현하고싶은게 가만히 몇초간 있으면 은신이 되는 시스템을 만들고싶은데 가만히 있을때 바로 투명화가 되는 코드는 구현을 했는데 

몇초간 기다린후에 작동하는 형식은 어떻게 해야하나요?

일단 기본적인 코드는 이런식으로 만들었습니다 다만 PlayerMoveEvent에서는 앞으로 달리면서 점프 후 착지 전에 빠르게 뒤를 보거나 다른 방향을 보면 가만히 있는다는 인식이 안되는데 이건 무슨 버그인가요? 물론 다시 다시 앞쪽을 보면 정상 작동은 합니다만...


@EventHandler
public void Still(PlayerMoveEvent e) {
    Player p = e.getPlayer();
    if (e.getFrom().getZ() != e.getTo().getZ() && e.getFrom().getX() != e.getTo().getX()) {
        p.removePotionEffect(PotionEffectType.INVISIBILITY);
        return;
    }

    p.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 10000, 1));
}

11개의 댓글

gabjuho
2022.06.14

runTask 함수 사용해보시겠어요?

runTask함수에 대해 잘 모르시면, 인터넷에 검색하시면 자세히 나와있어서 금방 익히실 수 있으실 거에요.

참고로, runTask 함수는 일정시간 후에 명령을 실행시키는 메서드입니다.

그리고, 두번째 질문은 이해가 잘 안되서 못해드리겠네용...

Resen
2022.06.14
@gabjuho

runTask는 중간에 취소가 가능한가요? 예를 들어서 플레이어가 runtask가 실행되는 도중 움직였다면 runTask를 도중 취소하는 방법으로?

gabjuho
2022.06.14
@Resen

cancelTask 라는 메서드가 있을 겁니다.

runTask 함수는 TaskID를 반환하는데, cancelTask에 그 값을 매개변수로 전달해주면 그 Task가 캔슬되는 형식입니다.

Resen
2022.06.14
@gabjuho

아하 그런 방법이 있군요 도움주셔서 감사합니다 혹시 정말 귀찮으시겠지만 코드 질문 하나만 더할수있을까요? 

RunTask로 구글링 돌리고 몇몇개 살펴보면서 코드를 만들었는데 아예 Runtask가 작동이 안되네요 ㅠ


    JavaPlugin plugin;
    static boolean isInvisibility;


    @EventHandler
    public void playerMove(PlayerMoveEvent e) {
        isInvisibility = false;

        Player p = e.getPlayer();
            if (p.getInventory().getItemInMainHand().getItemMeta().equals(Mas_1.MaS.getItemMeta()))
                if (!isInvisibility) {
                    int taskid = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
                        @Override
                        public void run() {
                            p.sendMessage("성공");
                            isInvisibility = true;
                            return;
                        }

                    }, 0L, 3 * 20L); //0 Tick initial delay, 20 Tick (1 Second) between repeats

                    if (e.getFrom().getZ() != e.getTo().getZ() && e.getFrom().getX() != e.getTo().getX()) {
                        Bukkit.getServer().getScheduler().cancelTask(taskid);
                        return;
                    }
                }
            if (isInvisibility) {
                if (e.getFrom().getZ() != e.getTo().getZ() && e.getFrom().getX() != e.getTo().getX()) {
                    p.removePotionEffect(PotionEffectType.INVISIBILITY);
                    return;
                }
            }
        }

}

gabjuho
2022.06.14
@Resen

RunTask 매서드 매개변수에 있는 plugin 이라는 값에 Main 클래스의 인스턴스가 들어가있나요?

그리고 오버라이드한 run매서드에 return; 빼보시겠어요?

Resen
2022.06.15
@gabjuho

아까운 시간 쓰면서 도와주셔서 정말 감사드립니다 ㅠㅠ 드디어 작동이 되네요 혼자 계속 생각했으면 안됬을텐데 정말 감사드립니다

gabjuho
2022.06.15
@Resen

작동됐다니 다행이네요 수고하세요!

Resen
2022.06.15
@gabjuho

전에 간단하게 테스트 하느라 확인을 못했는데 runtask가 무한 반복을 하네요?ㅠㅠ 계속 구글링 해도 Bukkit.getScheduler().cancelTask(taskid); 이걸로 멈추라는데 계속 멈추지가 않습니다


int stop = Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.getPlugin(Main.class), new Runnable() {
    @Override
    public void run() {
        if (number != -1) {
            if (number != 0) {
                number--; //-number
            } else {
                p.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 200, 1));
                number = 5;
                isInvisibility = true;
                Bukkit.getScheduler().cancelTask(stop);

            }
        }
    }
}, 0L, 20L);

 이런식으로 코드 되있고 cancelTask를 썼는데도 해결이 안되네요 ㅠ 어째서 무한반복하는지 아시나요?

gabjuho
2022.06.16
@Resen

stop을 run 메소드 밖에 선언 해놓았기 때문에, taskID가 안받아와진 것 같네요.

만약 내부에서 캔슬하는 방법을 찾고싶다면,

https://www.spigotmc.org/threads/cancel-task.222692/

다음 링크가 정확하게 질문자님의 질문과 일치할 겁니다.

해결책을 아주 자세하게 설명해주셨으니 읽어보세요!

Resen
2022.06.16
@gabjuho

끝까지 도와주셔서 정말 감사드립니다 계속 막혔는데 드디어 해결하네요 ㅠㅠ 정말 감사드려요

gabjuho
2022.06.16
@Resen

저도 옛날에 혼자서 고민했던 부분이였어서 공감되네요ㅠㅠ

플러그인 개발 응원합니다!